home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / editors / dme1312.of6 < prev    next >
Text File  |  1988-10-22  |  64KB  |  3,151 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!uflorida!gatech!bbn!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i010:  dme - programmer's text editor V1.31, Part02/06
  5. Message-ID: <9772@swan.ulowell.edu>
  6. Date: 22 Oct 88 04:29:35 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 3140
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
  12. Posting-number: Volume 2, Issue 10
  13. Archive-name: editors/dme131.2of6
  14.  
  15. # This is a shell archive.  Remove anything before this line
  16. # then unpack it by saving it in a file and typing "sh file"
  17. # (Files unpacked will be owned by you and have default permissions).
  18. # This archive contains the following files:
  19. #    ./src/subs.c
  20. #    ./src/refs.c
  21. #    ./src/main.c
  22. #    ./src/rexx.c
  23. #    ./src/Makefile
  24. #    ./src/cmd2.c
  25. #
  26. if `test ! -d ./src`
  27. then
  28.   mkdir ./src
  29.   echo "mkdir ./src"
  30. fi
  31. if `test ! -s ./src/subs.c`
  32. then
  33. echo "writing ./src/subs.c"
  34. cat > ./src/subs.c << '\Rogue\Monster\'
  35.  
  36. /*
  37.  *  SUBS.C
  38.  *
  39.  *    (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
  40.  *
  41.  *  Subroutines.
  42.  */
  43.  
  44. #include "defs.h"
  45.  
  46. /*
  47.  *  Create DME's text icon.
  48.  */
  49.  
  50. makemygadget(gad)
  51. register struct Gadget *gad;
  52. {
  53.     static unsigned long ga[] = {
  54.     0xFFFFFFFF,    /* 32 pixels across */
  55.     0x80FDCBFD,
  56.     0xFFFDDFFD,
  57.     0x80000001,
  58.     0x80DFDDDF,
  59.     0x80000001,
  60.     0xBC0EF00B,
  61.     0x80000001,
  62.     0xBFC00CDD,
  63.     0x80000001,
  64.     0xA00DF00F,
  65.     0x80000001,
  66.     0x80000001,
  67.  
  68.     0x80000001,
  69.     0x80FDCBFD,
  70.     0xFFFDDFFD,
  71.     0x80000001,
  72.     0x80DFDDDF,
  73.     0x80000001,
  74.     0xBC0EF00B,
  75.     0x80000001,
  76.     0xBFC00CDD,
  77.     0x80000001,
  78.     0xA00DF00F,
  79.     0x80000001,
  80.     0xFFFFFFFF
  81.     };
  82.     static struct Image image = {
  83.     0, 0, 20, sizeof(ga)/4/2, 2, (unsigned short *)ga, 3, 0, NULL
  84.     };
  85.     bzero(gad, sizeof(struct Gadget));
  86.     gad->Width = 20;
  87.     gad->Height = sizeof(ga)/4/2 + 1;
  88.     gad->Flags    = GADGIMAGE|GADGHCOMP;
  89.     gad->GadgetType   = BOOLGADGET;
  90.     gad->Activation = RELVERIFY|GADGIMMEDIATE;
  91.     gad->GadgetRender = (APTR)ℑ
  92. }
  93.  
  94. /*
  95.  * return index of first non space.  Returns 0 if no spaces found.
  96.  */
  97.  
  98. firstns(str)
  99. register char *str;
  100. {
  101.     register short i;
  102.  
  103.     for (i = 0; str[i] && str[i] == ' '; ++i);
  104.     if (str[i] == 0)
  105.     i = 0;
  106.     return(i);
  107. }
  108.  
  109. /*
  110.  *  Return index of last non-space, 0 if no spaces.
  111.  */
  112.  
  113. lastns(str)
  114. register char *str;
  115. {
  116.     register short i;
  117.  
  118.     for (i = strlen(str) - 1; i > 0 && str[i] == ' '; --i);
  119.     if (i < 0)
  120.     i = 0;
  121.     return(i);
  122. }
  123.  
  124. /*
  125.  *  Return length of word under cursor
  126.  */
  127.  
  128. wordlen(str)
  129. register char *str;
  130. {
  131.     register short i;
  132.  
  133.     for (i = 0; *str && *str != ' '; ++i, ++str);
  134.     return(i);
  135. }
  136.  
  137. /*
  138.  *  Find the path from some root device to a specific filename (src), and
  139.  *  stick the result in (dest).  If unable to backtrace along directories,
  140.  *  simply copy (src) into (dest)
  141.  *
  142.  *  Returns (1) if able to backtrace, (0) if not.
  143.  */
  144.  
  145. getpath(src, dest)
  146. char *src, *dest;
  147. {
  148.     register long flock, pflock;
  149.     register short len, total;
  150.     register FIB *fib = (FIB *)malloc(sizeof(FIB));
  151.     char c;
  152.  
  153.     dest[0] = 0;
  154.     total = 1;
  155.     flock = Lock(src, ACCESS_READ);
  156.     if (flock == NULL) {                           /* missing file?    */
  157.     for (len = strlen(src); len >= 0; --len) {
  158.         if (src[len] == '/') {
  159.         --len;
  160.         break;
  161.         }
  162.         if (src[len] == ':')
  163.         break;
  164.     }
  165.     if (c = src[len + 1]) {
  166.         strcpy(dest, src+len+2);
  167.         total = strlen(dest)+1;
  168.     }
  169.     src[len + 1] = 0;
  170.     flock = Lock(src, ACCESS_READ);
  171.     src[len + 1] = c;
  172.     }
  173.     if (flock) {
  174.     do {
  175.         pflock = ParentDir(flock);
  176.         if (Examine(flock, fib) == 0)
  177.         fib->fib_FileName[0] = 0;
  178.         if (fib->fib_FileName[0] == 0)
  179.         strcpy(fib->fib_FileName, "ram");
  180.         len = strlen(fib->fib_FileName);
  181.         bmov(dest, dest + len + 1, total);
  182.         dest[len] = (pflock) ? '/' : ':';
  183.         bmov(fib->fib_FileName, dest, len);
  184.         total += len + 1;
  185.         UnLock(flock);
  186.         flock = pflock;
  187.     } while(pflock);
  188.     len = strlen(dest) - 1;
  189.     if (dest[len] == '/')
  190.         dest[len] = 0;
  191.     return(1);
  192.     }
  193.     strcpy(dest, src);
  194.     return(0);
  195. }
  196.  
  197. /*
  198.  *  Allocation routines and other shortcuts
  199.  */
  200.  
  201. ubyte *
  202. allocb(bytes)
  203. {
  204.     return(AllocMem(bytes, MEMF_CLEAR|MEMF_PUBLIC));
  205. }
  206.  
  207. ubyte *
  208. allocl(lwords)
  209. {
  210.     return(AllocMem(lwords<<2, MEMF_CLEAR|MEMF_PUBLIC));
  211. }
  212.  
  213. bmovl(s,d,n)
  214. char *s,*d;
  215. {
  216.     bmov(s,d,n<<2);
  217. }
  218.  
  219. /*
  220.  *  Remove tabs in a buffer
  221.  */
  222.  
  223. detab(ibuf, obuf, maxlen)
  224. register char *ibuf, *obuf;
  225. {
  226.     register short i, j;
  227.  
  228.     maxlen -= 2;
  229.     for (i = j = 0; ibuf[i] && j < maxlen; ++i) {
  230.     if (ibuf[i] == 9) {
  231.         do {
  232.         obuf[j++] = ' ';
  233.         } while ((j & 7) && j < maxlen);
  234.     } else {
  235.         obuf[j++] = ibuf[i];
  236.     }
  237.     }
  238.     while (j && obuf[j-1] == ' ')
  239.     --j;
  240.     obuf[j] = 0;
  241.     return(j);
  242. }
  243.  
  244. xefgets(xfi, buf, max)
  245. char *buf;
  246. long xfi;
  247. {
  248.     char ebuf[256];
  249.     if (xfgets(xfi, ebuf, max) >= 0)
  250.     return(detab(ebuf, buf, max));
  251.     return(-1);
  252. }
  253.  
  254. ncstrcmp(s1, s2)
  255. register ubyte *s1, *s2;
  256. {
  257.     register ubyte c1, c2;
  258.  
  259.     for (;;) {
  260.     c1 = *s1;
  261.     c2 = *s2;
  262.     if (c1 >= 'A' && c1 <= 'Z') c1 |= 0x20;
  263.     if (c2 >= 'A' && c2 <= 'Z') c2 |= 0x20;
  264.     if (c1 != c2)
  265.         break;
  266.     if ((c1|c2) == 0)
  267.         return(0);
  268.     ++s1;
  269.     ++s2;
  270.     }
  271.     if (c1 < c2)
  272.     return(-1);
  273.     if (c1 > c2)
  274.     return(1);
  275. }
  276.  
  277. ED *
  278. finded(str, doff)
  279. char *str;
  280. {
  281.     register ED *ed;
  282.  
  283.     for (ed = (ED *)DBase.mlh_Head; ed->Node.mln_Succ; ed = (ED *)ed->Node.mln_Succ) {
  284.     if (strlen(ed->Name) >= doff && ncstrcmp(str, ed->Name+doff) == 0)
  285.         return(ed);
  286.     }
  287.     return(NULL);
  288. }
  289.  
  290. \Rogue\Monster\
  291. else
  292.   echo "will not over write ./src/subs.c"
  293. fi
  294. if [ `wc -c ./src/subs.c | awk '{printf $1}'` -ne 4407 ]
  295. then
  296. echo `wc -c ./src/subs.c | awk '{print "Got " $1 ", Expected " 4407}'`
  297. fi
  298. if `test ! -s ./src/refs.c`
  299. then
  300. echo "writing ./src/refs.c"
  301. cat > ./src/refs.c << '\Rogue\Monster\'
  302.  
  303. /*
  304.  *  REFS.C
  305.  *
  306.  *  Bringup a cross reference editor window.  The file S:dme.refs and
  307.  *  dme.refs in the current directory are searched for the reference.
  308.  *  If found, the file specified is searched and the segment specified
  309.  *  loaded as a new file in a new window.
  310.  */
  311.  
  312. #include "defs.h"
  313. #include <stdio.h>
  314.  
  315. #define PEN    struct _PEN
  316.  
  317. PEN {
  318.     MNODE   Node;
  319.     char    *path;
  320. };
  321.  
  322. extern char *breakout();
  323.  
  324. MLIST    PBase;        /*  special DME paths    */
  325.  
  326. /*
  327.  *  Special DME paths for REF and CTAGS
  328.  */
  329.  
  330. #ifndef NO_DO2
  331.  
  332. void
  333. do_addpath()
  334. {
  335.     register PEN *pen;
  336.     register short len = strlen(av[1]);
  337.  
  338.     for (pen = (PEN *)PBase.mlh_Head; pen->Node.mln_Succ; pen = (PEN *)pen->Node.mln_Succ) {
  339.     if (strcmp(av[1], pen->path) == 0)
  340.         return;
  341.     }
  342.     if (pen = malloc(sizeof(PEN)+len+2)) {
  343.     pen->path = (char *)(pen + 1);
  344.     strcpy(pen->path, av[1]);
  345.     switch(pen->path[len-1]) {
  346.     case ':':
  347.     case '/':
  348.         break;
  349.     default:
  350.         strcat(pen->path, "/");
  351.     }
  352.     }
  353.     AddTail(&PBase, pen);
  354. }
  355.  
  356. do_rempath()
  357. {
  358.     register PEN *pen, *npen;
  359.  
  360.     for (pen = (PEN *)PBase.mlh_Head; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  361.     if (wildcmp(av[1], pen->path)) {
  362.         Remove(pen);
  363.         free(pen);
  364.     }
  365.     }
  366. }
  367.  
  368. #endif
  369.  
  370. #ifndef NO_DO_CTAGS
  371.  
  372. /*
  373.  *  Implement ctags
  374.  */
  375.  
  376. void
  377. do_ctags()
  378. {
  379.     char str[64];
  380.     char path[128];
  381.     char buf[128];
  382.     char sbuf[128];
  383.     long xfi;
  384.     short xlen;
  385.     short slen;
  386.     short dbaselen;
  387.     long oldlock = CurrentDir(Ep->dirlock);
  388.     ED *ed;
  389.  
  390.     {
  391.     register short i, j;
  392.  
  393.     for (i = Ep->Column; Current[i] == ' '; ++i);
  394.     for (j = i; ; ++j) {
  395.         register short c = Current[j];
  396.         if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9'))
  397.         continue;
  398.         break;
  399.     }
  400.     j -= i;
  401.     if (j > 63)
  402.         j = 63;
  403.     bmov(Current+i, str, j);
  404.     str[j] = 0;
  405.     xlen = j;
  406.     }
  407.     if (!Ep->iconmode)
  408.     title("search tags");
  409.     {
  410.     long xfi;
  411.     PEN *pen, *npen;
  412.     register long i;
  413.     register short j, len;
  414.  
  415.     dbaselen = dirpart(Ep->Name);
  416.     bmov(Ep->Name, path, dbaselen);
  417.     strcpy(path+dbaselen, "tags");
  418.  
  419.     /*
  420.      *  Note: pen not used first pass and set to list head, so next
  421.      *  pass it will be the first element.
  422.      *
  423.      *  Note2:  The file path depends on several factors.  (1) tags in
  424.      *        'current' directory, use path to name of current window.
  425.      *        (2) tags in directory in DME special path, use special
  426.      *        path.  (3) tag entry is a full path name, override
  427.      *        previous directories.
  428.      */
  429.  
  430.     for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  431.         mountrequest(0);
  432.         if (xfi = xfopen(path, "r", 4096)) {
  433.         mountrequest(1);
  434.         while ((len = xefgets(xfi, buf, 128)) >= 0) {
  435.             for (j = 0; buf[j] && buf[j] != ' '; ++j);
  436.             if (j == 0 || buf[0] == '#')
  437.             continue;
  438.             if (j == xlen && strncmp(str, buf, j) == 0) {
  439.             while (buf[j] == ' ')
  440.                 ++j;
  441.             /*
  442.              *  Extract the file name into str.  If the
  443.              *  filename does not contain an absolute path,
  444.              *  prepend it with such.
  445.              */
  446.             {
  447.                 char prep = 1;
  448.                 for (i = 0; buf[j] && buf[j] != ' '; ++i, ++j) {
  449.                 str[i] = buf[j];
  450.                 if (str[i] == ':')
  451.                     prep = 0;
  452.                 }
  453.                 if (prep) {
  454.                 bmov(str, str + dbaselen, i);
  455.                 bmov(path, str, dbaselen);
  456.                 i += dbaselen;
  457.                 }
  458.             }
  459.             str[i] = 0;
  460.  
  461.             while (buf[j] && buf[j] != '^')     /*  SEARCH ARG */
  462.                 ++j;
  463.             xfclose(xfi);
  464.             if (buf[j] != '^') {
  465.                 title("tags error");
  466.                 goto done;
  467.             }
  468.             ++j;
  469.             strcpy(sbuf, buf+j);
  470.             slen = strlen(sbuf);
  471.             if ((ed = finded(str, 0)) == NULL) {
  472.                 strcpy(buf, "newwindow newfile ");
  473.                 strcat(buf, str);
  474.                 do_command(buf);
  475.                 ed = finded(str, 0);
  476.             } else {
  477.                 WindowToFront(ed->Win);
  478.                 ActivateWindow(ed->Win);
  479.             }
  480.             if (ed == NULL) {
  481.                 title("unable to load file");
  482.                 goto done;
  483.             }
  484.             text_switch(ed->Win);
  485.             if (Ep->iconmode)
  486.                 uniconify();
  487.             else
  488.                 text_cursor(0);
  489.             for (i = 0; i < ed->Lines; ++i) {
  490.                 if (strncmp(ed->List[i], sbuf, slen) == 0)
  491.                 break;
  492.             }
  493.             sprintf(buf, "first goto %ld", i+1);
  494.             do_command(buf);
  495.             goto done;
  496.             }
  497.         }
  498.         xfclose(xfi);
  499.         } else {
  500.         mountrequest(1);
  501.         }
  502.         if (npen->Node.mln_Succ) {
  503.         strcpy(path, npen->path);
  504.         strcat(path, "tags");
  505.         dbaselen = strlen(npen->path);
  506.         }
  507.     }
  508.     title("tag not found");
  509.     }
  510. done:
  511.     CurrentDir(oldlock);
  512. }
  513.  
  514. #endif
  515.  
  516. #ifndef NO_DO_REFS
  517.  
  518. /*
  519.  *  Implement references
  520.  */
  521.  
  522. void
  523. do_refs()
  524. {
  525.     char str[256];
  526.     char path[128];
  527.     char *srch;
  528.     char *file;
  529.     char *estr;
  530.     long len;
  531.     int bcnt = 10;
  532.     register short i, j;
  533.     short slen, elen;
  534.     long xfi, xfj;
  535.     short tmph, tmpw;
  536.     long oldlock = CurrentDir(Ep->dirlock);
  537.  
  538.     for (i = Ep->Column; Current[i] == ' '; ++i);     /*  skip spaces     */
  539.     for (j = i       ; ; ++j) {
  540.     if (Current[j] && Current[j] != ' ')
  541.         continue;
  542.     break;
  543.     }
  544.     j -= i;
  545.     if (j > 63)
  546.     j = 63;
  547.     bmov(Current+i, str, j);
  548.     str[j] = 0;
  549.     title("search .refs");
  550.     {
  551.     register PEN *pen;
  552.     register PEN *npen;
  553.  
  554.     strcpy(path, "dme.refs");
  555.     mountrequest(0);
  556.     for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  557.         if (searchref(path, str, &srch, &file, &len, &estr)) {
  558.         mountrequest(1);
  559.         goto found;
  560.         }
  561.         if (npen->Node.mln_Succ) {
  562.         strcpy(path, npen->path);
  563.         strcat(path, "dme.refs");
  564.         }
  565.     }
  566.     title("Reference not found");
  567.     mountrequest(1);
  568.     goto done;
  569.     }
  570. found:
  571.     title("search file");
  572.     slen = strlen(srch);
  573.     if (estr)
  574.     elen = strlen(estr);
  575.     if (xfi = xfopen(file, "r", 4096)) {
  576.     short lenstr;
  577.     while ((lenstr = xefgets(xfi, str, 256)) >= 0) {
  578.         if (strncmp(str, srch, slen) == 0) {
  579.         title("load..");
  580.         if (xfj = xfopen("t:dme_ref", "w", 1024)) {
  581.             tmph = 0;
  582.             tmpw = 0;
  583.             do {
  584.             if (lenstr > tmpw)
  585.                 tmpw = strlen(str);
  586.             ++tmph;
  587.             xfwrite(xfj, str, strlen(str));
  588.             xfwrite(xfj, "\n", 1);
  589.             if (estr && strncmp(str,estr,elen) == 0)
  590.                 break;
  591.             --len;
  592.             } while ((lenstr=xefgets(xfi, str, 256)) >= 0 && len);
  593.             xfclose(xfj);
  594.             if (tmph > 10)
  595.             tmph = 10;
  596.             if (tmpw > 80)
  597.             tmpw = 80;
  598.             sprintf(str, "tmpheight %ld tmpwidth %ld newwindow newfile t:dme_ref", (tmph<<3)+24, (tmpw<<3)+24);
  599.             do_command(str);
  600.             unlink("t:dme_ref");
  601.         } else {
  602.             title("Unable to open t:dme_ref for write");
  603.         }
  604.         xfclose(xfi);
  605.         free(srch);
  606.         free(file);
  607.         if (estr)
  608.             free(estr);
  609.         goto done;
  610.         }
  611.         if (--bcnt == 0) {      /* check break every so so  */
  612.         bcnt = 50;
  613.         if (breakcheck())
  614.             break;
  615.         }
  616.     }
  617.     xfclose(xfi);
  618.     title("Search failed");
  619.     } else {
  620.     title("Unable to open sub document");
  621.     }
  622.     free(srch);
  623.     free(file);
  624.     if (estr)
  625.     free(estr);
  626. done:
  627.     CurrentDir(oldlock);
  628. }
  629.  
  630. /*
  631.  *  Reference file format:
  632.  *
  633.  *  `key' `lines' `file' `searchstring'
  634.  *
  635.  *  where `lines' can be a string instead ... like a read-until, otherwise
  636.  *  the number of lines to read from the reference.
  637.  */
  638.  
  639. searchref(file, find, psstr, pfile, plines, pestr)
  640. char *file, *find;
  641. char **psstr, **pfile, **pestr;
  642. long *plines;
  643. {
  644.     long xfi;
  645.     char buf[256];
  646.     char *ptr, *base;
  647.     char *b1, *b2, *b3, *b4;
  648.     char quoted;
  649.  
  650.     if (xfi = xfopen(file, "r", 4096)) {
  651.     while (xefgets(xfi,(base=buf), 256) >= 0) {
  652.         if (buf[0]=='#')
  653.         continue;
  654.         ptr = breakout(&base, "ed, &b1);
  655.         if (ptr && *ptr && strncmp(ptr, find, strlen(ptr)) == 0) {
  656.         if (ptr = breakout(&base, "ed, &b2)) {
  657.             *pestr = NULL;
  658.             *plines = atoi(ptr);
  659.             if (*plines == 0) {
  660.             *pestr = (char *)malloc(strlen(ptr)+1);
  661.             strcpy(*pestr, ptr);
  662.             }
  663.             if (ptr = breakout(&base, "ed, &b3)) {
  664.             *pfile = (char *)malloc(strlen(ptr)+1);
  665.             strcpy(*pfile, ptr);
  666.             if (ptr = breakout(&base, "ed, &b4)) {
  667.                 *psstr = (char *)malloc(strlen(ptr)+1);
  668.                 strcpy(*psstr, ptr);
  669.                 xfclose(xfi);
  670.                 if (b1) free(b1);
  671.                 if (b2) free(b2);
  672.                 if (b3) free(b3);
  673.                 if (b4) free(b4);
  674.                 return(1);
  675.             }
  676.             free(*pfile);
  677.             if (b4)
  678.                 free(b4);
  679.             }
  680.             if (pestr)
  681.             free (*pestr);
  682.             if (b3)
  683.             free (b3);
  684.         }
  685.         if (b2)
  686.             free(b2);
  687.         }
  688.         if (b1)
  689.         free(b1);
  690.     }
  691.     xfclose(xfi);
  692.     }
  693.     return(0);
  694. }
  695.  
  696. #endif
  697.  
  698. #ifndef NO_DO_CTAGS
  699.  
  700. dirpart(str)
  701. register char *str;
  702. {
  703.     register short i;
  704.  
  705.     for (i = strlen(str) - 1; i >= 0; --i) {
  706.     if (str[i] == '/' || str[i] == ':')
  707.         break;
  708.     }
  709.     return(i+1);
  710. }
  711.  
  712. #endif
  713.  
  714. \Rogue\Monster\
  715. else
  716.   echo "will not over write ./src/refs.c"
  717. fi
  718. if [ `wc -c ./src/refs.c | awk '{printf $1}'` -ne 8371 ]
  719. then
  720. echo `wc -c ./src/refs.c | awk '{print "Got " $1 ", Expected " 8371}'`
  721. fi
  722. if `test ! -s ./src/main.c`
  723. then
  724. echo "writing ./src/main.c"
  725. cat > ./src/main.c << '\Rogue\Monster\'
  726.  
  727. /*
  728.  * MAIN.C
  729.  *
  730.  *    (C)Copyright 1987 by Matthew Dillon, All Rights Reserved.
  731.  *
  732.  */
  733.  
  734. #include "defs.h"
  735. #include <local/deemu.h>
  736. #include <local/ipc.h>
  737.  
  738. short Deemu[] = {
  739.     DMSTRT, 0, 0,
  740.     DMNW,   0,10,32,16,-64,-80,0xFFFF,
  741.     DMEND,  0, 0
  742. };
  743.  
  744. #define DMNWOFF 4
  745.  
  746. #define IDCMPFLAGS   CLOSEWINDOW|NEWSIZE|RAWKEY|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE|MENUPICK
  747.  
  748. extern WIN *OpenWindow();
  749. extern char *menu_cmd();
  750.  
  751. NW Nw = {
  752.    0, 1, 0  , 0  , -1, -1,  /*    width, height filled in by program */
  753.    IDCMPFLAGS,
  754.    ACTIVATE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|RMBTRAP,
  755.    NULL, NULL, (ubyte *)"   WAIT   ",
  756.    NULL, NULL,
  757.    32, 32, -1, -1,
  758.    WBENCHSCREEN
  759. };
  760.  
  761. short Sharedrefs;
  762. short Oldtlen = 999;      /*  Old Title Length      */
  763. struct MsgPort *Sharedport;
  764. DISKOBJ *Do;
  765. WBS    *Wbs;
  766.  
  767. WIN *Win;
  768. RP  *Rp;
  769.  
  770. short Xsize,  Ysize;        /* font character sizes        */
  771. short Rows,  Columns;        /* character rows/cols available       */
  772. short Xbase,  Ybase;        /* offset pixel base for display       */
  773. short XTbase,YTbase;        /* used for text display           */
  774. short Xpixs,  Ypixs;        /* actual # X/Y pixels available       */
  775. short Mx, My;
  776.  
  777. ubyte *av[8];
  778. char Quitflag;
  779. char Overide;
  780. char SizeOveride;
  781. char Wdisable = 1;        /* Disable icon save               */
  782. char MShowTitle, MForceTitle;
  783. short Nwwidth, Nwheight, Nwtopedge, Nwleftedge, Nwtmpwidth, Nwtmpheight;
  784.  
  785. PORT *IPCPort;
  786. PORT *IPCRPort;
  787. long Mask;
  788.  
  789. int Enable_Abort;
  790.  
  791. extern WIN   *opensharedwindow();
  792.  
  793. static char *Ffile;
  794.  
  795. main(mac, mav)
  796. char *mav[];
  797. {
  798.     char nf, ni;        /*    # files on command line     */
  799.     char notdone;        /*    for endless loop        */
  800.     char iawm = 0;        /*    overide mouse buttons        */
  801.     char dontwait = 0;        /*    don't wait for a message    */
  802.     short i;
  803.     short Code;
  804.     PROC *proc = (PROC *)FindTask(NULL);
  805.     long origlock;
  806.  
  807.     origlock = CurrentDir(DupLock(proc->pr_CurrentDir));
  808.  
  809.     NewList(&DBase);
  810.     NewList(&PBase);
  811.     if (!openlibs(INTUITION_LIB|GRAPHICS_LIB))
  812.     exiterr("cannot open intuition or graphics library");
  813.     initipc();
  814.  
  815.     InitDeemuNW(Deemu+DMNWOFF, &Nw);
  816.  
  817.     init_command();
  818.  
  819.     Nwwidth    = Nw.Width;    /*  Parameters for new windows    */
  820.     Nwheight    = Nw.Height;
  821.     Nwtopedge    = Nw.TopEdge;
  822.     Nwleftedge    = Nw.LeftEdge;
  823.  
  824.     Enable_Abort= 0;        /*  disable break        */
  825.  
  826.     String  = (char *)malloc(1);        /*  initialize scanf variable   */
  827.     *String = 0;
  828.  
  829.  
  830.     if (mac == 0) {             /*  WORKBENCH STARTUP           */
  831.  
  832.     Wdisable = 0;        /*  allow icon save        */
  833.     Wbs = (WBS *)mav;
  834.     if (!openlibs(ICON_LIB))
  835.         exiterr("unable to open icon library");
  836.     UnLock(CurrentDir(DupLock(Wbs->sm_ArgList[0].wa_Lock)));   /* Tool */
  837.     Do = GetDiskObject(Wbs->sm_ArgList[0].wa_Name);
  838.     if (Do == NULL)
  839.         exiterr("unable to get disk object");
  840.     mac = 99;
  841.     }
  842.  
  843. #if AREXX
  844.     mountrequest(0);
  845.     openrexx();     /* do this after the last possible call to exiterr() */
  846.     mountrequest(1);
  847. #endif
  848.  
  849.     resethash();
  850.  
  851.     if (Do) {
  852.     ops(Do->do_ToolTypes, 1);
  853.     nf = Wbs->sm_NumArgs - 1;
  854.     UnLock(CurrentDir(DupLock(Wbs->sm_ArgList[0].wa_Lock)));
  855.     } else {
  856.     nf = ops(mav+1, 0);
  857.     }
  858.  
  859.     for (ni = 0, i = 1; i < mac; ++i) {
  860.     register char *str;
  861.     register DISKOBJ *dso;
  862.     if (Wbs) {
  863.         if (i > nf)
  864.         break;
  865.         str = Wbs->sm_ArgList[i].wa_Name;
  866.         UnLock(CurrentDir(DupLock(Wbs->sm_ArgList[i].wa_Lock)));
  867.         if (dso = GetDiskObject(Wbs->sm_ArgList[i].wa_Name)) {
  868.         ops(dso->do_ToolTypes, 1);
  869.         FreeDiskObject(dso);
  870.         }
  871.     } else {
  872.         str = mav[i];
  873.         if (*str == '-')
  874.         continue;
  875.     }
  876.     do_newwindow(nf > 1, ni * 10);
  877.     ++ni;
  878.     av[0] = (ubyte *)"newfile";
  879.     av[1] = (ubyte *)str;
  880.     do_edit();
  881.     MForceTitle = 1;
  882.     window_title();
  883.     }
  884.     if (nf == 0)                    /* no files to edit */
  885.     do_newwindow(nf > 1, ni * 10);
  886.  
  887.     mountrequest(0);
  888.     av[0] = NULL;
  889.     av[1] = (ubyte *)"s:.edrc";
  890.     do_source();
  891.     av[0] = NULL;
  892.     av[1] = (ubyte *)((Ffile) ? Ffile : ".edrc");
  893.     do_source();
  894.     mountrequest(1);
  895.     {                /*    1.29c    */
  896.     register ED *ep;
  897.     register ED *eb = Ep;
  898.     if (eb) {
  899.         for (ep = (ED *)eb->Node.mln_Succ; ep->Node.mln_Succ; ep = (ED *)ep->Node.mln_Succ) {
  900.         ep->Tabstop = eb->Tabstop;
  901.         ep->Margin  = eb->Margin;
  902.         ep->Insertmode = eb->Insertmode;
  903.         ep->IgnoreCase = eb->IgnoreCase;
  904.         ep->Wordwrap   = eb->Wordwrap;
  905.         if (eb->Font) {
  906.             ep->Font = eb->Font;
  907.             ++eb->Font->tf_Accessors;
  908.         }
  909.         }
  910.     }
  911.     }
  912.     title("DME V1.31 \251Copyright 1988 by Matthew Dillon,  All Rights Reserved                  ");
  913.     Mask |= 1 << Win->UserPort->mp_SigBit;
  914. loop:
  915.     if (!Ep->iconmode)
  916.     text_cursor(1);
  917.     for (notdone = 1; !Quitflag && notdone;) {
  918.     char mmove = 0;
  919.     short mqual;
  920.  
  921.     if (!Ep->iconmode)
  922.         window_title();
  923.     if (dontwait) {
  924.         --dontwait;
  925.     } else {
  926.         Wait(Mask);
  927.     }
  928.  
  929.     /*
  930.      *  NOTE: due to operation of breakcheck(), the userport signal
  931.      *  may not be set even if there are messages pending.
  932.      *
  933.      *  NOTE2: CheckPort() requires dres.library, which will be loaded
  934.      *  if IPCPort exists because the IPC needs it also.
  935.      */
  936.  
  937.     if (IPCPort && CheckPort(IPCPort))
  938.         ipchandler();
  939.     {
  940.         register IMESS *im;
  941.         while (im = (IMESS *)GetMsg(Win->UserPort)) {
  942.         Msgchk = 1;
  943.         Abortcommand = 0;
  944.         Code = im->Code;
  945.         if (im->IDCMPWindow != Win) {
  946.             Overide = 0;
  947.             if (Comlinemode)
  948.             escapecomlinemode();
  949.             text_sync();
  950.             MShowTitle = 0;
  951.             if (!Ep->iconmode)
  952.             window_title();
  953.             if (text_switch(im->IDCMPWindow) == 0) {
  954.             ReplyMsg(im);
  955.             continue;
  956.             }
  957.         }
  958.         Mx = im->MouseX;
  959.         My = im->MouseY;
  960.         switch(im->Class) {
  961.         case NEWSIZE:
  962.             if (!Ep->iconmode) {
  963.             if (Comlinemode)
  964.                 escapecomlinemode();
  965.             set_window_params();
  966.             if (!text_sync())
  967.             text_redisplay();
  968.             text_cursor(1);
  969.             }
  970.             break;
  971.         case MOUSEBUTTONS:
  972.             switch(Code) {
  973.             case SELECTDOWN:
  974.             case MENUDOWN:
  975.             if (Ep->iconmode || iawm) {
  976.                 uniconify();
  977.                 break;
  978.             }
  979.             ReportMouse(-1, Win);
  980.             uniconify();
  981.             text_cursor(0);
  982.             keyctl(NULL, im->Code|0x80, im->Qualifier);
  983.             text_cursor(1);
  984.             break;
  985.             case SELECTUP:
  986.             case MENUUP:
  987.             ReportMouse(0, Win);
  988.             break;
  989.             }
  990.             break;
  991.         case RAWKEY:
  992.             if ((im->Code & 0x80) == 0) {
  993.             /*  Handled in command interpreter.
  994.             if (Ep->iconmode) {
  995.                 uniconify();
  996.                 break;
  997.             }
  998.             */
  999.             text_cursor(0);
  1000.             keyctl(im, im->Code, im->Qualifier);
  1001.             text_cursor(1);
  1002.             }
  1003.             break;
  1004.         case MENUPICK:
  1005.             {
  1006.             register char *str = menu_cmd(im);
  1007.             if (str) {
  1008.                 str = strcpy(malloc(strlen(str)+1), str);
  1009.                 text_cursor(0);
  1010.                 do_command(str);
  1011.                 free(str);
  1012.                 text_cursor(1);
  1013.             }
  1014.             }
  1015.             break;
  1016.         case CLOSEWINDOW:
  1017.             if (Comlinemode)
  1018.             escapecomlinemode();
  1019.             text_sync();
  1020.             notdone = 0;
  1021.             break;
  1022.         case ACTIVEWINDOW:
  1023.             if (!Ep->iconmode)
  1024.             iawm = 1;
  1025.             break;
  1026.         case MOUSEMOVE:
  1027.             mmove = 1;
  1028.             mqual = im->Qualifier;
  1029.             break;
  1030.         }
  1031.         if (im)
  1032.             ReplyMsg(im);
  1033.         if (notdone == 0 || Quitflag) {
  1034.             dontwait = 2;
  1035.             goto boom;
  1036.         }
  1037.         }
  1038.     }
  1039.  
  1040.     iawm = 0;
  1041.     if (mmove) {
  1042.         uniconify();
  1043.         mmove = 0;
  1044.         text_cursor(0);
  1045.         keyctl(NULL, QMOVE, mqual);
  1046.         text_cursor(1);
  1047.     }
  1048.     closesharedwindow(NULL);
  1049.     }
  1050. boom:
  1051.     text_sync();
  1052.     if (Ep->Modified && !Overide) {
  1053.     uniconify();
  1054.     Overide = 1;
  1055.     title("*** File has been modified ***");
  1056.     Quitflag = 0;
  1057.     goto loop;
  1058.     }
  1059.     SetWindowTitles(Win, "", -1);
  1060.     text_uninit();                        /* uninitialize text portion    */
  1061.     closesharedwindow(Win);
  1062.     if (((ED *)DBase.mlh_Head)->Node.mln_Succ) {
  1063.     Quitflag = 0;
  1064.     Win = Ep->Win;              /* make arbitrary other window act. */
  1065.     Rp = Win->RPort;
  1066.     if (!Ep->iconmode)
  1067.         set_window_params();
  1068.     text_load();
  1069.     MShowTitle = 0;
  1070.     goto loop;
  1071.     }
  1072.     closesharedwindow(NULL);
  1073.     if (Do)
  1074.     FreeDiskObject(Do);
  1075. #if AREXX
  1076.     closerexx();
  1077. #endif
  1078.     UnLock(CurrentDir(origlock));
  1079.     if (IPCPort)
  1080.     CloseIPC(IPCPort);
  1081.     if (IPCRPort)
  1082.     DeletePort(IPCRPort);
  1083.     closelibs(-1);
  1084.     dealloc_hash();
  1085. }
  1086.  
  1087. ipchandler()
  1088. {
  1089.     register IPCMSG *msg;
  1090.     register char *ptr;
  1091.     while (msg = (IPCMSG *)GetMsg(IPCPort)) {
  1092.     register long error = 0;
  1093.     if (ptr = (char *)msg->TBuf) {      /*  Valid msg,  */
  1094.         register ED *ed;
  1095.                         /*    For this project  */
  1096.         if (ptr[0] == 0)
  1097.         ed = Ep;
  1098.         else if ((ed = finded(ptr, 0)) == NULL)
  1099.         error = IF_NOTFND;
  1100.         if (ed) {
  1101.         if (ed != Ep)
  1102.             text_switch(ed->Win);
  1103.         if (!Ep->iconmode)
  1104.             text_cursor(0);
  1105.         while (*ptr++);                 /*  Skip Project Name */
  1106.         do_command(ptr);
  1107.         }
  1108.     }
  1109.     ReplyIPC(msg, NULL, 0, error);
  1110.     }
  1111. }
  1112.  
  1113. /*
  1114.  *  If it is possible, create an IPC port for DME.  IF_ALLOC specifies that
  1115.  *  incomming static messages should be re-allocated automatically because
  1116.  *  we will be destroying the input buffer for messages we process.
  1117.  */
  1118.  
  1119. initipc()
  1120. {
  1121.     if (openlibs(DRES_LIB)) {
  1122.     if (IPCPort = OpenIPC("dme.CMD", IF_ALLOC)) {
  1123.         Mask |= 1 << IPCPort->mp_SigBit;
  1124.         IPCRPort = CreatePort(NULL,0);
  1125.     }
  1126.     }
  1127. }
  1128.  
  1129. /*
  1130.  *  IPC appname projname command
  1131.  */
  1132.  
  1133. void
  1134. do_ipc()
  1135. {
  1136.     char *buf;
  1137.     char buf2[64];
  1138.     IPCMSG msg;
  1139.     short len;
  1140.  
  1141.     if (!IPCPort)
  1142.     initipc();
  1143.     if (!IPCPort) {
  1144.     Abortcommand = 1;
  1145.     title("dres.library not installed");
  1146.     return;
  1147.     }
  1148.     buf = malloc(len = strlen(av[2])+strlen(av[3])+2);
  1149.     strcpy(buf, av[2]);
  1150.     strcpy(buf+strlen(buf)+1, av[3]);
  1151.     strcpy(buf2, av[1]);
  1152.     strcat(buf2, ".CMD");
  1153.     msg.Msg.mn_ReplyPort = IPCRPort;
  1154.     msg.TBuf = (APTR)buf;
  1155.     msg.TLen = len;
  1156.     msg.TFlags = IF_NOCOPY;
  1157.     DoIPC2(buf2, &msg, ipchandler, IPCPort);
  1158.     if (msg.RFlags & IF_ERROR) {
  1159.     if (msg.RFlags & IF_NOAPP)
  1160.         title("Application not found");
  1161.     else
  1162.         title("Remote error");
  1163.     }
  1164.     FreeIPC(&msg);
  1165.     free(buf);
  1166. }
  1167.  
  1168. do_iconify()
  1169. {
  1170.     text_sync();
  1171.     if (!Comlinemode)
  1172.     iconify();
  1173. }
  1174.  
  1175. do_tomouse()
  1176. {
  1177.     text_position((Mx-Xbase)/Xsize, (My-Ybase)/Ysize);
  1178. }
  1179.  
  1180. iconify()
  1181. {
  1182.     if (!Ep->iconmode) {
  1183.     Ep->Winx      = Win->LeftEdge;
  1184.     Ep->Winy      = Win->TopEdge;
  1185.     Ep->Winwidth  = Win->Width;
  1186.     Ep->Winheight = Win->Height;
  1187.     Nw.Height = 10;
  1188.     Nw.Width  = 20 + 5*8 + strlen(Ep->Name)*8;
  1189.     Nw.LeftEdge= Ep->IWinx;
  1190.     Nw.TopEdge = Ep->IWiny;
  1191.     if (Nw.LeftEdge + Nw.Width > Win->WScreen->Width)
  1192.         Nw.LeftEdge = Win->WScreen->Width - Nw.Width;
  1193.     if (Nw.TopEdge + Nw.Height > Win->WScreen->Height)
  1194.         Nw.TopEdge = Win->WScreen->Height - Nw.Height;
  1195.     Nw.Title = Ep->Wtitle;
  1196.     Nw.Flags &= ~(WINDOWSIZING|WINDOWDEPTH|ACTIVATE);
  1197.     Nw.Flags |= BORDERLESS;
  1198.     Nw.BlockPen = (Ep->Modified) ? 3 : -1;
  1199.     sprintf(Ep->Wtitle, "%s     ", Ep->Name);
  1200.     if (Win->Flags & WINDOWACTIVE)      /*  KTS */
  1201.         Nw.Flags |= ACTIVATE;
  1202.     closesharedwindow(Win);
  1203.     Win = Ep->Win = opensharedwindow(&Nw);
  1204.     Nw.BlockPen = -1;
  1205.     Nw.Flags |= WINDOWSIZING|WINDOWDEPTH;
  1206.     Nw.Flags &= ~BORDERLESS;
  1207.     Rp = Win->RPort;
  1208.     }
  1209.     Ep->iconmode = 1;
  1210. }
  1211.  
  1212. uniconify()
  1213. {
  1214.     if (Ep->iconmode) {
  1215.     Ep->IWinx = Win->LeftEdge;
  1216.     Ep->IWiny = Win->TopEdge;
  1217.     closesharedwindow(Win);
  1218.     Nw.LeftEdge = Ep->Winx;
  1219.     Nw.TopEdge  = Ep->Winy;
  1220.     Nw.Width    = Ep->Winwidth;
  1221.     Nw.Height   = Ep->Winheight;
  1222.     Nw.Title    = Ep->Wtitle;
  1223.     Win = Ep->Win = opensharedwindow(&Nw);
  1224.     menu_strip(Win);
  1225.     Rp = Win->RPort;
  1226.     if (Ep->Font)
  1227.         SetFont(Rp, Ep->Font);
  1228.     set_window_params();
  1229.     if (!text_sync())
  1230.         text_redisplay();
  1231.     text_cursor(1);
  1232.     MShowTitle = 0;
  1233.     window_title();
  1234.     }
  1235.     Ep->iconmode = 0;
  1236. }
  1237.  
  1238.  
  1239. do_newwindow(makesmall, deltaheight)
  1240. {
  1241.     WIN *win;
  1242.     int msadj = makesmall;
  1243.  
  1244.     if (SizeOveride)
  1245.     msadj = 0;
  1246.     if (Ep)
  1247.     text_sync();
  1248.     Nw.Title = (ubyte *)"    OK    ";
  1249.     Nw.Width = (Nwtmpwidth) ? Nwtmpwidth : Nwwidth;
  1250.     Nw.Height= (Nwtmpheight)? Nwtmpheight: Nwheight;
  1251.     Nwtmpwidth = Nwtmpheight = 0;
  1252.     Nw.LeftEdge = Nwleftedge;
  1253.     Nw.TopEdge    = Nwtopedge;
  1254.     if (msadj > 0) {                    /* deltaheight must be valid    */
  1255.     Nw.TopEdge = deltaheight + 16;
  1256.     Nw.LeftEdge= 10*8;
  1257.     Nw.Flags &= ~ACTIVATE;
  1258.     Nw.Width = 40*8;
  1259.     Nw.Height= 10*8;
  1260.     if (Nw.TopEdge + Nw.Height > 200)
  1261.         Nw.TopEdge = deltaheight = 200 - Nw.Height;
  1262.     }
  1263.     win = opensharedwindow(&Nw);
  1264.     menu_strip(win);
  1265.     Nw.Flags |= ACTIVATE;
  1266.     if (win) {
  1267.     Win = win;            /* set new window   */
  1268.     Rp = Win->RPort;
  1269.     set_window_params();
  1270.     text_init();                    /* initialize       */
  1271.     text_load();
  1272.     if (makesmall != -1)            /* if deltaheight valid */
  1273.         Ep->IWiny = deltaheight + 16;
  1274.     }
  1275. }
  1276.  
  1277. WIN *
  1278. TOpenWindow(nw)
  1279. NW *nw;
  1280. {
  1281.     WIN *win;
  1282.  
  1283.     while ((win = OpenWindow(nw)) == NULL) {
  1284.     if (nw->Width < 50 || nw->Height < 50)
  1285.         break;
  1286.     nw->Width -= 10;
  1287.     nw->Height-= 10;
  1288.     }
  1289.     return(win);
  1290. }
  1291.  
  1292.  
  1293. WIN *
  1294. opensharedwindow(nw)
  1295. NW *nw;
  1296. {
  1297.     WIN *win;
  1298.  
  1299.     if (Sharedport)
  1300.     nw->IDCMPFlags = NULL;
  1301.     else
  1302.     nw->IDCMPFlags = IDCMPFLAGS;
  1303.     win = TOpenWindow(nw);
  1304.     if (win) {
  1305.     if (Sharedport) {
  1306.         win->UserPort = Sharedport;
  1307.         ModifyIDCMP(win, IDCMPFLAGS);
  1308.     } else {
  1309.         Sharedport = win->UserPort;
  1310.     }
  1311.     ++Sharedrefs;
  1312.     }
  1313.     return(win);
  1314. }
  1315.  
  1316.  
  1317. closesharedwindow(win)
  1318. WIN *win;
  1319. {
  1320.     static WIN *wunlink;
  1321.     register IMESS *im;
  1322.     char notoktoclosenow = 0;
  1323.  
  1324.     if (win) {
  1325.     SetWindowTitles(win, "", -1);
  1326.     ClearMenuStrip(win);
  1327.     Forbid();
  1328.     win->UserPort = NULL;
  1329.     ModifyIDCMP(win, GADGETUP);     /* NEVER occurs */
  1330.  
  1331.     notoktoclosenow = 1;
  1332.  
  1333.     Permit();
  1334.     if (notoktoclosenow) {
  1335.         win->UserData = (char *)wunlink;
  1336.         wunlink = win;
  1337.     } else {
  1338.         CloseWindow(win);
  1339.     }
  1340.     --Sharedrefs;
  1341.     } else {
  1342.     if (Sharedrefs == 0 && Sharedport) {
  1343.         DeletePort(Sharedport);
  1344.         Sharedport = NULL;
  1345.     }
  1346.     for (win = wunlink; win; win = wunlink) {
  1347.         wunlink = (WIN *)win->UserData;
  1348.         CloseWindow(win);
  1349.     }
  1350.     wunlink = NULL;
  1351.     }
  1352. }
  1353.  
  1354.  
  1355. getyn(text)
  1356. char *text;
  1357. {
  1358.     int result;
  1359.     ITEXT *body, *pos, *neg;
  1360.  
  1361.     body = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
  1362.     pos  = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
  1363.     neg  = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
  1364.     bzero(body, sizeof(ITEXT));
  1365.     bzero(pos , sizeof(ITEXT));
  1366.     bzero(neg , sizeof(ITEXT));
  1367.     body->BackPen = pos->BackPen = neg->BackPen = 1;
  1368.     body->DrawMode= pos->DrawMode= neg->DrawMode= AUTODRAWMODE;
  1369.     body->LeftEdge = 10;
  1370.     body->TopEdge  = 12;
  1371.     body->IText    = (ubyte *)text;
  1372.     pos->LeftEdge = AUTOLEFTEDGE;
  1373.     pos->TopEdge = AUTOTOPEDGE;
  1374.     pos->IText = (ubyte *)"OK";
  1375.     neg->LeftEdge = AUTOLEFTEDGE;
  1376.     neg->TopEdge = AUTOTOPEDGE;
  1377.     neg->IText = (ubyte *)"CANCEL";
  1378.     result = AutoRequest(Win,body,pos,neg,0,0,320,58);
  1379.     FreeMem(body, sizeof(ITEXT));
  1380.     FreeMem(pos , sizeof(ITEXT));
  1381.     FreeMem(neg , sizeof(ITEXT));
  1382.     return(result);
  1383. }
  1384.  
  1385.  
  1386. title(buf)
  1387. char *buf;
  1388. {
  1389.     SetWindowTitles(Win, buf, -1);
  1390.     Oldtlen = 999;
  1391.     MShowTitle = 3;
  1392. }
  1393.  
  1394. window_title()
  1395. {
  1396.     register int len, maxlen;
  1397.  
  1398.     if (memoryfail) {
  1399.     title(" -- NO MEMORY -- ");
  1400.     memoryfail = 0;
  1401.     text_redisplay();
  1402.     }
  1403.     if (MForceTitle) {
  1404.     MShowTitle = 0;
  1405.     MForceTitle = 0;
  1406.     }
  1407.     if (MShowTitle) {
  1408.     --MShowTitle;
  1409.     return(0);
  1410.     }
  1411.     {
  1412.     register char *mod;
  1413.     FONT *oldfont;
  1414.  
  1415.     mod = (Ep->Modified) ? " (modified)" : "          ";
  1416.     sprintf(Ep->Wtitle, "%3ld/%-3ld %3ld %s%s  ", text_lineno(), text_lines(), text_colno()+1, text_name(), mod);
  1417.     if (!text_imode())
  1418.         strcat(Ep->Wtitle, "Ovr ");
  1419.     len = strlen(Ep->Wtitle);
  1420.     if (len < Columns && Columns < 128) {
  1421.         bset(Ep->Wtitle+len, Columns - len + 1, ' ');
  1422.         Ep->Wtitle[Columns + 1] = 0;
  1423.     }
  1424.  
  1425.     /*
  1426.      *  Update title
  1427.      */
  1428.  
  1429.     oldfont = Win->RPort->Font;
  1430.     SetFont(Win->RPort, Win->WScreen->RastPort.Font);
  1431.  
  1432.     Win->Title = Ep->Wtitle;
  1433.     SetAPen(Rp, 0);
  1434.     SetBPen(Rp, 1);
  1435.     Move(Rp, 30, Win->RPort->Font->tf_Baseline+1);
  1436.     maxlen = (Win->Width-96)/Win->RPort->Font->tf_XSize;
  1437.     if (maxlen < 0)
  1438.         maxlen = 0;
  1439.     if (len > maxlen)
  1440.         len = Oldtlen = maxlen;
  1441.     if (Oldtlen > maxlen)
  1442.         Oldtlen = maxlen;
  1443.     Text(Rp, Ep->Wtitle, len);      /*  No flash                    */
  1444.     while (Oldtlen - len >= (int)sizeof(Space)) {
  1445.         Text(Rp, Space, sizeof(Space));
  1446.         Oldtlen -= sizeof(Space);
  1447.     }
  1448.     if (Oldtlen - len > 0)
  1449.         Text(Rp, Space, Oldtlen - len);
  1450.     Oldtlen = len;            /*  Oldtlen might have been <    */
  1451.     SetAPen(Rp, 1);
  1452.     SetBPen(Rp, 0);
  1453.  
  1454.     SetFont(Win->RPort, oldfont);
  1455.     }
  1456. }
  1457.  
  1458. set_window_params()
  1459. {
  1460.     Xsize = Rp->Font->tf_XSize;
  1461.     Ysize = Rp->Font->tf_YSize;
  1462.     Xbase = Win->BorderLeft;
  1463.     Ybase = Win->BorderTop;
  1464.     Xpixs   = Win->Width - Win->BorderRight - Xbase;
  1465.     Ypixs   = Win->Height- Win->BorderBottom- Ybase;
  1466.     Columns = Xpixs / Xsize;
  1467.     Rows    = Ypixs / Ysize;
  1468.     XTbase  =  Xbase;
  1469.     YTbase  =  Ybase + Rp->Font->tf_Baseline;
  1470. }
  1471.  
  1472.  
  1473. exiterr(str)
  1474. char *str;
  1475. {
  1476.     if (Output()) {
  1477.     Write(Output(),str,strlen(str));
  1478.     Write(Output(),"\n",1);
  1479.     }
  1480.     exit(1);
  1481. }
  1482.  
  1483.  
  1484. /*
  1485.  *  Check break by scanning pending messages in the I stream for a ^C.
  1486.  *  Msgchk forces a check, else the check is only made if the signal is
  1487.  *  set in the I stream (the signal is reset).
  1488.  */
  1489.  
  1490. breakcheck()
  1491. {
  1492.     IMESS *im;
  1493.     register struct List *list = &Win->UserPort->mp_MsgList;
  1494.  
  1495.     if (Msgchk || (SetSignal(0,0) & (1<<Win->UserPort->mp_SigBit))) {
  1496.     Msgchk = 0;
  1497.     SetSignal(0,1<<Win->UserPort->mp_SigBit);
  1498.  
  1499.     im = (IMESS *)list->lh_Head;
  1500.     Forbid();
  1501.     for (; im != &list->lh_Tail; im = (IMESS *)im->ExecMessage.mn_Node.ln_Succ) {
  1502.         if (im->Class == RAWKEY && (im->Qualifier & 0xFB) == 0x08 &&
  1503.         im->Code == CtlC) {
  1504.  
  1505.         Permit();
  1506.         SetSignal(SIGBREAKF_CTRL_C,SIGBREAKF_CTRL_C);
  1507.         return(1);
  1508.         }
  1509.     }
  1510.     Permit();
  1511.     }
  1512.     return(0);
  1513. }
  1514.  
  1515. breakreset()
  1516. {
  1517.     SetSignal(0, SIGBREAKF_CTRL_C);
  1518. }
  1519.  
  1520. /*
  1521.  *  leftedge n
  1522.  *  topedge  n
  1523.  *  width    n
  1524.  *  height   n
  1525.  *  tmpwidth  n
  1526.  *  tmpheight n
  1527.  */
  1528.  
  1529. void
  1530. do_windowparm()
  1531. {
  1532.     int val = atoi(av[1]);
  1533.  
  1534.     if (av[0][0] == 't' && av[0][1] == 'm') {   /*  tmpwidth/tmpheight  */
  1535.     if (av[0][3] == 'w')
  1536.         Nwtmpwidth = val;
  1537.     if (av[0][3] == 'h')
  1538.         Nwtmpheight= val;
  1539.     return;
  1540.     }
  1541.     switch(av[0][0]) {
  1542.     case 'l':
  1543.     Nwleftedge = val;
  1544.     break;
  1545.     case 't':
  1546.     Nwtopedge = val;
  1547.     break;
  1548.     case 'w':
  1549.     Nwwidth = val;
  1550.     break;
  1551.     case 'h':
  1552.     Nwheight = val;
  1553.     break;
  1554.     }
  1555. }
  1556.  
  1557. /*
  1558.  *  resize cols rows
  1559.  */
  1560.  
  1561. do_resize()
  1562. {
  1563.     int cols = atoi(av[1]);
  1564.     int rows = atoi(av[2]);
  1565.     short width = (cols*Win->RPort->Font->tf_XSize) + Win->BorderLeft + Win->BorderRight;
  1566.     short height= (rows*Win->RPort->Font->tf_YSize) + Win->BorderTop + Win->BorderBottom;
  1567.  
  1568.     if (width < 16 || height < 16 ||
  1569.     width > Win->WScreen->Width - Win->LeftEdge ||
  1570.     height > Win->WScreen->Height - Win->TopEdge) {
  1571.     title ("window too big (try moving to upper left corner and retrying)");
  1572.     return(0);
  1573.     }
  1574.     SizeWindow(Win, width - Win->Width, height - Win->Height);
  1575.     Delay(50*2);    /* wait 2 seconds */
  1576. }
  1577.  
  1578. ops(av, iswb)
  1579. register char *av[];
  1580. {
  1581.     register short nonops;
  1582.     register short i;
  1583.     register long val;
  1584.     register char *str;
  1585.  
  1586.     for (i = nonops = 0; str = av[i]; ++i) {
  1587.     if (iswb) {
  1588.         if (strncmp(str, "ARG", 3) == 0) {
  1589.         while (*str && *str != '-')
  1590.             ++str;
  1591.         }
  1592.     }
  1593.     if (*str == '-') {
  1594.         val = atoi(str+2);
  1595.         switch(str[1]) {
  1596.         case 'f':
  1597.         Ffile = str+2;
  1598.         break;
  1599.         case 'b':
  1600.         SizeOveride = 1;
  1601.         break;
  1602.         case 't':
  1603.         Nwtopedge = val;
  1604.         break;
  1605.         case 'l':
  1606.         Nwleftedge= val;
  1607.         break;
  1608.         case 'w':
  1609.         SizeOveride = 1;
  1610.         Nwwidth   = val;
  1611.         break;
  1612.         case 'h':
  1613.         SizeOveride = 1;
  1614.         Nwheight  = val;
  1615.         break;
  1616.         }
  1617.     } else {
  1618.         ++nonops;
  1619.     }
  1620.     }
  1621.     return(nonops);
  1622. }
  1623.  
  1624.  
  1625.  
  1626. \Rogue\Monster\
  1627. else
  1628.   echo "will not over write ./src/main.c"
  1629. fi
  1630. if [ `wc -c ./src/main.c | awk '{printf $1}'` -ne 19086 ]
  1631. then
  1632. echo `wc -c ./src/main.c | awk '{print "Got " $1 ", Expected " 19086}'`
  1633. fi
  1634. if `test ! -s ./src/rexx.c`
  1635. then
  1636. echo "writing ./src/rexx.c"
  1637. cat > ./src/rexx.c << '\Rogue\Monster\'
  1638.  
  1639. /*
  1640.  *  REXX.C
  1641.  *
  1642.  *    (c) Copyright 1987 by Kim DeVaughn, All Rights Reserved
  1643.  *
  1644.  *  ARexx interface code, etc.
  1645.  *
  1646.  */
  1647.  
  1648.  
  1649. #include "defs.h"
  1650. #include "rexx.h"
  1651.  
  1652. #if AREXX
  1653.  
  1654. int foundcmd;        /* control for implicit ARexx macro invocation   */
  1655. int cmderr;        /* global command error flag for do_rexx()'s use */
  1656.  
  1657. /*
  1658. APTR OpenLibrary();
  1659. APTR FindPort();
  1660. APTR GetMsg();
  1661. */
  1662. APTR CreateRexxMsg();
  1663. APTR CreateArgstring();
  1664.  
  1665. struct RxsLib *RexxSysBase;
  1666.  
  1667.  
  1668.  
  1669. /*
  1670.  * initialization for ARexx ... just open rexsyslib.library
  1671.  */
  1672.  
  1673. void
  1674. openrexx()
  1675. {
  1676.     RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", (ULONG)RXSVERS);
  1677.     return;
  1678. }
  1679.  
  1680.  
  1681.  
  1682. /*
  1683.  * cleanup any open ARexx stuff ...  just close rexsyslib.library for now
  1684.  */
  1685.  
  1686. void
  1687. closerexx()
  1688. {
  1689.     if (RexxSysBase) {
  1690.     CloseLibrary(RexxSysBase);
  1691.     }
  1692.     return();
  1693. }
  1694.  
  1695.  
  1696.  
  1697. /*
  1698.  *  explicit invocation interface between do_command() and do_rexx
  1699.  *  for ARexx macros having NO arguments (i.e., for the "rx" command)
  1700.  */
  1701.  
  1702. do_rx()
  1703. {
  1704.     do_rexx(av[1]);
  1705.     return();
  1706. }
  1707.  
  1708.  
  1709.  
  1710. /*
  1711.  *  explicit invocation interface between do_command() and do_rexx
  1712.  *  for ARexx macros having ONE argument (i.e., for the "rx1" command)
  1713.  */
  1714.  
  1715. do_rx1()
  1716. {
  1717.     char macbuf[256];
  1718.  
  1719.     strcpy(macbuf, av[1]);
  1720.     strcat(macbuf, " ");
  1721.     strcat(macbuf, av[2]);
  1722.     do_rexx(macbuf);
  1723.     return();
  1724. }
  1725.  
  1726.  
  1727.  
  1728. /*
  1729.  *  explicit invocation interface between do_command() and do_rexx
  1730.  *  for ARexx macros having TWO arguments (i.e., for the "rx2" command)
  1731.  */
  1732.  
  1733. do_rx2()
  1734. {
  1735.     char macbuf[256];
  1736.  
  1737.     strcpy(macbuf, av[1]);
  1738.     strcat(macbuf, " ");
  1739.     strcat(macbuf, av[2]);
  1740.     strcat(macbuf, " ");
  1741.     strcat(macbuf, av[3]);
  1742.     do_rexx(macbuf);
  1743.     return();
  1744. }
  1745.  
  1746.  
  1747.  
  1748. /*
  1749.  *  implicit invocation interface between do_command() and do_rexx
  1750.  *  for ARexx macros implicitly called; arbitrary number of arguments
  1751.  */
  1752.  
  1753. do_rxImplied(cmd, args)
  1754. char *cmd;
  1755. char *args;
  1756. {
  1757.     char macbuf[256];
  1758.  
  1759.     strcpy(macbuf, cmd);
  1760.     strcat(macbuf, " ");
  1761.     strcat(macbuf, args);
  1762.     do_rexx(macbuf);
  1763.     return();
  1764. }
  1765.  
  1766.  
  1767.  
  1768. /*
  1769.  *  issue a command to ARexx ...
  1770.  */
  1771.  
  1772. do_rexx(macstr)
  1773. char *macstr;
  1774. {
  1775.     struct RexxArg *macarg;
  1776.  
  1777.     struct MsgPort  RexxPort;
  1778.     struct MsgPort *ARexxPort;
  1779.  
  1780.     struct RexxMsg *macptr;
  1781.     struct RexxMsg *cmdptr;
  1782.  
  1783.     char host[16];
  1784.     char hexbuf[12];        /* should only need 9 bytes */
  1785.     char errmsg[80];        /* don't build a larger error message */
  1786.  
  1787.     int  ret;
  1788.     int  err;
  1789.  
  1790.  
  1791.     if (RexxSysBase == 0) {
  1792.     title("Unknown Command   -   No Macros:  ARexx Not Installed ");   /* no rexxsyslib */
  1793.     return(0);
  1794.     }
  1795.  
  1796.  
  1797.     ClearMem(&RexxPort, sizeof(struct MsgPort));
  1798.     strcpy(host, "DME");
  1799.     sprintf(hexbuf, "%08x", &RexxPort);
  1800.     strcat(host, hexbuf);
  1801.     InitPort(&RexxPort, host);      /* need to error check this */
  1802.     AddPort(&RexxPort);
  1803.     /* return here if InitPort failed */
  1804.  
  1805.  
  1806.     if (macarg = (struct RexxArg *)CreateArgstring(macstr, strlen(macstr))) {
  1807.     if (macptr = (struct RexxMsg *)CreateRexxMsg(&RexxPort, "dme", host)) {
  1808.         ACTION(macptr) = RXCOMM;
  1809.         ARG0(macptr)   = (STRPTR)macarg;
  1810.  
  1811.         Forbid();
  1812.         if (ARexxPort = (struct MsgPort *)FindPort("REXX")) {
  1813.         PutMsg(ARexxPort, macptr);
  1814.         Permit();
  1815.         title("Calling ARexx Macro ... ");
  1816.  
  1817.         for (;;) {
  1818.             WaitPort(&RexxPort);
  1819.             cmdptr = (struct RexxMsg *)GetMsg(&RexxPort);
  1820.  
  1821.             if (IsRexxMsg(cmdptr)) {
  1822.  
  1823.             foundcmd = 0;
  1824.             cmderr = CMD_INITIAL;
  1825.             ret = do_command(ARG0(cmdptr));
  1826.             err = cmderr;
  1827.             if (foundcmd) {
  1828.                 ret = (ret == 1) ? 0 : 5;   /* cmd error:  RC = 5  */
  1829.             } else {
  1830.                 ret = do_rexx(ARG0(cmdptr));    /* another macro? */
  1831.             }
  1832.  
  1833.             RESULT1(cmdptr) = ret;
  1834.             RESULT2(cmdptr) = 0;
  1835.             ReplyMsg(cmdptr);
  1836.             }
  1837.             do_command("null");     /* a kludge to set "foundcmd" */
  1838.             if (macptr == cmdptr) break;
  1839.         }
  1840.  
  1841.  
  1842.         if (ret = RESULT1(cmdptr)) {
  1843.             if (RESULT2(cmdptr)) {
  1844.             if (RESULT2(cmdptr) == 1) {
  1845.                 title("Unknown Command ");
  1846.             } else {
  1847.                 sprintf(errmsg, "ARexx Macro Error:  Code = %d  Severity = %d ", RESULT2(cmdptr), ret);
  1848.                 title(errmsg);
  1849.             }
  1850.             } else {
  1851.             sprintf(errmsg, "User Specified Macro Error:  RC = %d ", ret);
  1852.             title(errmsg);
  1853.             }
  1854.         } else {
  1855.             if (err <= TITLE_THRESHHOLD) {
  1856.             title("OK ");
  1857.             }
  1858.         }
  1859.         ret = ret + err;
  1860.         } else {
  1861.         Permit();
  1862.         title("Unknown Command   -   No Macros:  ARexx Not Active ");   /* no REXX port */
  1863.  
  1864.         ret = -1;
  1865.         }
  1866.         DeleteRexxMsg(macptr);
  1867.     } else {
  1868.         title("CreateRexxMsg() Failed ");   /* may be overkill, and not need to ckeck this */
  1869.         ret = -1;
  1870.     }
  1871.     DeleteArgstring(macarg);
  1872.     } else {
  1873.     title("CreateArgstring() Failed ");     /* may be overkill, and not need to check this */
  1874.     ret = -1;
  1875.     }
  1876.  
  1877.  
  1878.     RemPort(&RexxPort);
  1879.     FreePort(&RexxPort);
  1880.     return(ret);
  1881. }
  1882.  
  1883. #endif
  1884.  
  1885. \Rogue\Monster\
  1886. else
  1887.   echo "will not over write ./src/rexx.c"
  1888. fi
  1889. if [ `wc -c ./src/rexx.c | awk '{printf $1}'` -ne 4689 ]
  1890. then
  1891. echo `wc -c ./src/rexx.c | awk '{print "Got " $1 ", Expected " 4689}'`
  1892. fi
  1893. if `test ! -s ./src/Makefile`
  1894. then
  1895. echo "writing ./src/Makefile"
  1896. cat > ./src/Makefile << '\Rogue\Monster\'
  1897.  
  1898. #   Makefile for DME
  1899. #
  1900. #   You *need* my support libraries to compile this
  1901.  
  1902. SYMS=    include:symbols.m
  1903. SYMC=    include:local/makesymbols.c
  1904. OD=    T:
  1905.  
  1906. EXE= /c/dme
  1907.  
  1908. AFLAGS= -iSYS2:asm
  1909. CFLAGS= +L +I$(SYMS) -E1000
  1910.  
  1911. OB0=   $(OD)main.o
  1912. OB1=   $(OD)command.o
  1913. OB2=   $(OD)keyboard.o
  1914. OB3=   $(OD)globals.o
  1915. OB4=   $(OD)cmd1.o
  1916. OB5=   $(OD)cmd2.o
  1917. OB6=   $(OD)cmd3.o
  1918. OB7=   $(OD)subs.o
  1919. OB8=   $(OD)refs.o
  1920. OB9=   $(OD)filereq.o
  1921. OBA=   $(OD)menu.o
  1922. OBB=   $(OD)mods.o
  1923. OBC=   $(OD)rexx.o
  1924. OBD=   $(OD)rexxbind.o
  1925.  
  1926. SR0=   main.c
  1927. SR1=   command.c
  1928. SR2=   keyboard.c
  1929. SR3=   globals.c
  1930. SR4=   cmd1.c
  1931. SR5=   cmd2.c
  1932. SR6=   cmd3.c
  1933. SR7=   subs.c
  1934. SR8=   refs.c
  1935. SR9=   filereq.c
  1936. SRA=   menu.c
  1937. SRB=   mods.c
  1938. SRC=   rexx.c
  1939. SRD=   rexxbind.asm
  1940.  
  1941. OBJS= $(OB0) $(OB1) $(OB2) $(OB3) $(OB4) $(OB5) $(OB6) $(OB7) $(OB8) $(OB9) $(OBA) $(OBB) $(OBC) $(OBD)
  1942.  
  1943. $(EXE): $(SYMS) $(OBJS)
  1944.     ln +Q $(OBJS) -ldres -lsup32 -lc32 -O $(EXE)
  1945.  
  1946. clean:
  1947.     -delete $(OBJS)
  1948.  
  1949. $(OB0): $(SR0)
  1950.     cc $(CFLAGS) $(SR0) -o $(OB0)
  1951. $(OB1): $(SR1)
  1952.     cc $(CFLAGS) $(SR1) -o $(OB1)
  1953. $(OB2): $(SR2)
  1954.     cc $(CFLAGS) $(SR2) -o $(OB2)
  1955. $(OB3): $(SR3)
  1956.     cc $(CFLAGS) $(SR3) -o $(OB3)
  1957. $(OB4): $(SR4)
  1958.     cc $(CFLAGS) $(SR4) -o $(OB4)
  1959. $(OB5): $(SR5)
  1960.     cc $(CFLAGS) $(SR5) -o $(OB5)
  1961. $(OB6): $(SR6)
  1962.     cc $(CFLAGS) $(SR6) -o $(OB6)
  1963. $(OB7): $(SR7)
  1964.     cc $(CFLAGS) $(SR7) -o $(OB7)
  1965. $(OB8): $(SR8)
  1966.     cc $(CFLAGS) $(SR8) -o $(OB8)
  1967. $(OB9): $(SR9)
  1968.     cc $(CFLAGS) $(SR9) -o $(OB9)
  1969. $(OBA): $(SRA)
  1970.     cc $(CFLAGS) $(SRA) -o $(OBA)
  1971. $(OBB): $(SRB)
  1972.     cc $(CFLAGS) $(SRB) -o $(OBB)
  1973. $(OBC): $(SRC)
  1974.     cc $(CFLAGS) $(SRC) -o $(OBC)
  1975. $(OBD): $(SRD)
  1976.     as $(AFLAGS) $(SRD) -o $(OBD)
  1977.  
  1978. $(SYMS):    $(SYMC)
  1979.     make -f include:local/Makefile
  1980.  
  1981.  
  1982. \Rogue\Monster\
  1983. else
  1984.   echo "will not over write ./src/Makefile"
  1985. fi
  1986. if [ `wc -c ./src/Makefile | awk '{printf $1}'` -ne 1655 ]
  1987. then
  1988. echo `wc -c ./src/Makefile | awk '{print "Got " $1 ", Expected " 1655}'`
  1989. fi
  1990. if `test ! -s ./src/cmd2.c`
  1991. then
  1992. echo "writing ./src/cmd2.c"
  1993. cat > ./src/cmd2.c << '\Rogue\Monster\'
  1994.  
  1995. /*
  1996.  * CMD2.C   (was TEXT2.C)
  1997.  *
  1998.  *    (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
  1999.  */
  2000.  
  2001. #include "defs.h"
  2002. #include <stdio.h>
  2003.  
  2004. #define nomemory()  {memoryfail = 1;}
  2005.  
  2006. #if AREXX
  2007. #include "rexx.h"
  2008. extern int foundcmd;       /* control for implicit ARexx macro invocation   */
  2009. extern int cmderr;       /* global command error flag for do_rexx()'s use */
  2010. #endif
  2011.  
  2012. extern char MForceTitle;
  2013. extern void do_bmove();
  2014.  
  2015.  
  2016.  
  2017. ED *
  2018. uninit_init(ep)
  2019. register ED *ep;
  2020. {
  2021.     short iwinx, iwiny;
  2022.     char  tabstop, margin, insertmode, wordwrap;
  2023.     FONT  *font;
  2024.     long lock = DupLock(ep->dirlock);
  2025.  
  2026.     iwinx = ep->IWinx;
  2027.     iwiny = ep->IWiny;
  2028.     tabstop= ep->Tabstop;
  2029.     margin = ep->Margin;
  2030.     insertmode = ep->Insertmode;
  2031.     wordwrap = ep->Wordwrap;
  2032.     font = ep->Font;
  2033.     ep->Font = NULL;
  2034.     text_uninit();
  2035.     text_init();
  2036.     ep = Ep;
  2037.     if (ep->Font)
  2038.     CloseFont(ep->Font);
  2039.     ep->Font = font;
  2040.     ep->IWiny = iwiny;
  2041.     ep->IWinx = iwinx;
  2042.     ep->Tabstop = tabstop;
  2043.     ep->Margin    = margin;
  2044.     ep->Insertmode = insertmode;
  2045.     ep->Wordwrap = wordwrap;
  2046.     ep->Modified = 0;
  2047.     ep->Line = ep->Topline = 0;
  2048.     UnLock(ep->dirlock);
  2049.     ep->dirlock = lock;
  2050.     return(ep);
  2051. }
  2052.  
  2053.  
  2054. do_remeol()
  2055. {
  2056.     Current[Clen = Ep->Column] = 0;
  2057.     text_sync();
  2058.     text_redisplaycurrline();
  2059. }
  2060.  
  2061. do_wleft()
  2062. {
  2063.     register ED *ep = Ep;
  2064.     register ubyte *ptr;
  2065.     register int i;
  2066.  
  2067.     for (;;) {
  2068.     i = ep->Column;
  2069.     if (i == 0)
  2070.         goto prevline;
  2071.     --i;
  2072.     while (i && Current[i] == ' ')
  2073.         --i;
  2074.     if (i == 0 && Current[0] == ' ') {
  2075. prevline:
  2076.         if (Comlinemode || ep->Line == 0) {
  2077.         i = ep->Column;
  2078.         break;
  2079.         }
  2080.         text_sync();
  2081.         --ep->Line;
  2082.         text_load();
  2083.         ep->Column = Clen;
  2084.         continue;
  2085.     }
  2086.     while (i && Current[i] != ' ')
  2087.         --i;
  2088.     if (Current[i] == ' ')
  2089.         ++i;
  2090.     break;
  2091.     }
  2092.     ep->Column = i;
  2093.     text_sync();
  2094. }
  2095.  
  2096.  
  2097. do_wright()
  2098. {
  2099.     register ubyte *ptr;
  2100.     register ED *ep = Ep;
  2101.     register int i;
  2102.  
  2103.     for (;;) {
  2104.     i = ep->Column;
  2105.     if (i == Clen)
  2106.         goto nextline;
  2107.     while (i != Clen && Current[i] != ' ')  /* skip past current word */
  2108.         ++i;
  2109.     while (i != Clen && Current[i] == ' ')  /* to beg. of next word   */
  2110.         ++i;
  2111.     if (i == Clen) {
  2112. nextline:
  2113.         if (Comlinemode || ep->Line == ep->Lines - 1) {
  2114.         i = ep->Column;
  2115.         break;
  2116.         }
  2117.         text_sync();
  2118.         ++ep->Line;
  2119.         text_load();
  2120.         ep->Column = i = 0;
  2121.         if (Current[0] != ' ')
  2122.         break;
  2123.         continue;
  2124.     }
  2125.     break;
  2126.     }
  2127.     ep->Column = i;
  2128.     text_sync();
  2129. }
  2130.  
  2131.  
  2132. do_split()              /* split line in two at cursor pos */
  2133. {
  2134.     ubyte buf[256];
  2135.     register ED *ep = Ep;
  2136.  
  2137.     strcpy(buf, Current+ep->Column);
  2138.     Current[Clen = ep->Column] = '\0';
  2139.     text_sync();
  2140.     SetAPen(Rp, 0);
  2141.     if (Nsu == 0)
  2142.     RectFill(Rp, COL(0), ROW(ep->Line-ep->Topline), Xbase+Xpixs, ROW(ep->Line-ep->Topline+1)-1);
  2143.     SetAPen(Rp, 1);
  2144.     text_displayseg(ep->Line - ep->Topline, 1);
  2145.     do_downadd();
  2146.     do_insline();
  2147.     strcpy(Current, buf);
  2148.     Clen = strlen(Current);
  2149.     text_sync();
  2150.     text_displayseg(ep->Line - ep->Topline, 1);
  2151.     do_up();
  2152. }
  2153.  
  2154. do_join()
  2155. {
  2156.     register int i = Clen, j;
  2157.     register ED *ep = Ep;
  2158.  
  2159.     if (ep->Line + 1 < ep->Lines && strlen(ep->List[ep->Line+1])+i <= 253) {
  2160.     if (i && Current[i-1] != ' ')
  2161.         Current[i++] = ' ';
  2162.     strcpy(Current+i, ep->List[ep->Line+1]);
  2163.     for (j = i; Current[j] == ' '; ++j);
  2164.     for (; i >= 0 && Current[i] == ' '; --i);
  2165.     if (j > i+2)
  2166.         bmov(Current+j, Current+i+2, strlen(Current+j)+1);
  2167.     Clen = strlen(Current);
  2168.     text_sync();
  2169.     text_displayseg(ep->Line - ep->Topline, 1);
  2170.     do_down();
  2171.     do_deline();
  2172.     do_up();
  2173.     return(1);
  2174.     }
  2175.     return(0);
  2176. }
  2177.  
  2178. do_margin()
  2179. {
  2180.     Ep->Margin = atoi(av[1]);
  2181. }
  2182.  
  2183. do_wordwrap()
  2184. {
  2185.     register ED *ep = Ep;
  2186.  
  2187.     if (av[1][1] == 'n')
  2188.     ep->Wordwrap = 1;
  2189.     if (av[1][1] == 'f')
  2190.     ep->Wordwrap = 0;
  2191.     if (av[1][0] == 't')
  2192.     ep->Wordwrap = 1 - ep->Wordwrap;
  2193.     if (ep->Wordwrap)
  2194.     title("Wordwrap ON");
  2195.     else
  2196.     title("Wordwrap OFF");
  2197. }
  2198.  
  2199. /*
  2200.  * n == -1  :    force reformat entire paragraph
  2201.  * n ==  0  :    only until line equalizes (from text_write())
  2202.  *
  2203.  * What is a paragraph?   A paragraph ends whenever the left justification
  2204.  * gets larger, or on a blank line.
  2205.  */
  2206.  
  2207. do_reformat(n)
  2208. {
  2209.     register char *str;
  2210.     register ED *ep = Ep;
  2211.     int nlok, lnsc, fnst, fnsc;
  2212.     int column = ep->Column;
  2213.     int srow   = ep->Line;
  2214.     int crow   = srow;
  2215.     int erow   = srow;
  2216.     short dins = 0;        /* relative insert lines/delete lines   */
  2217.     char moded = 0;        /* any modifications done at all?        */
  2218.     char checked = 0;        /* for cursor positioning.            */
  2219.  
  2220.     if (ep->Margin == 0)
  2221.     ep->Margin = 75;
  2222.  
  2223.     ++Nsu;
  2224.     for (;;) {
  2225.     str = (char *)ep->List[ep->Line+1];
  2226.     fnst = 0;
  2227.     fnsc = firstns(Current);
  2228.     nlok = (ep->Line + 1 < ep->Lines && fnsc >= (fnst=firstns(str)));
  2229.     if (nlok && str[0] == 0)
  2230.         nlok = 0;
  2231.     lnsc = lastns(Current);
  2232.     if (lnsc < ep->Margin) {    /* space at end of line for marg-lnsc-2 letter word   */
  2233.         if (nlok == 0)        /* but no more data to joinup   */
  2234.         break;          /* done */
  2235.         if (ep->Margin - lnsc - 2 >= wordlen(str+fnst)) {
  2236.         ep->Column = 0;
  2237.         Clen = lastns(Current);
  2238.         if (Current[Clen])
  2239.             ++Clen;
  2240.         moded = 1;
  2241.         --dins;
  2242.         if (do_join())
  2243.             continue;
  2244.         ++dins;
  2245.         title("Error, Margin > 124");
  2246.         break;
  2247.         }
  2248.         if (n == 0)        /* if couldn't mod line, and text_write, don't update any more */
  2249.         break;
  2250.         do_down();
  2251.         erow = ep->Line;
  2252.         continue;
  2253.     }
  2254.                 /* no space, need to split    */
  2255.                 /* find start of prev word    */
  2256.     for (;;) {
  2257.         register int i = lnsc;
  2258.         while (i && Current[i] != ' ')
  2259.         --i;
  2260.         lnsc = i;
  2261.         if (i >= ep->Margin) {
  2262.         while (i && Current[i] == ' ')
  2263.             --i;
  2264.         if (i < ep->Margin)
  2265.             break;
  2266.         lnsc = i;
  2267.         continue;
  2268.         }
  2269.         break;
  2270.     }
  2271.     if (lnsc) {             /* ok to split at word          */
  2272.         ++lnsc;
  2273.         ++dins;
  2274.         ep->Column = lnsc;
  2275.         do_split(); /* Split at point LNSC          */
  2276.         do_down();          /* must insert proper amount?   */
  2277.         {
  2278.         int indent = (nlok == 0) ? fnsc : fnst;
  2279.         if (!checked) {
  2280.             checked = 1;
  2281.             if (lnsc <= column) {   /* if split before cursor   */
  2282.             column = column - ep->Column + indent;
  2283.             ++crow;
  2284.             }
  2285.         }
  2286.         if (Clen + indent < 253) {
  2287.             bmov(Current, Current + indent, strlen(Current)+1);
  2288.             bset(Current, indent, ' ');
  2289.             Clen += indent;
  2290.         }
  2291.         }
  2292.         erow = ep->Line;
  2293.         continue;
  2294.     }
  2295.     if (n == 0)
  2296.         break;
  2297.     do_down();
  2298.     }
  2299.     if (column < 0 || column > 200)
  2300.     column = 0;
  2301.     if (srow >= ep->Lines) {
  2302.     srow = ep->Lines - 1;
  2303.     goto ra;
  2304.     }
  2305.     if (dins || srow < ep->Topline || srow >= ep->Topline + Rows) {
  2306. ra:
  2307.     text_sync();
  2308.     --Nsu;
  2309.     ep->Line = crow;
  2310.     ep->Column = column;
  2311.     text_load();
  2312.     if (!text_sync())
  2313.         text_redisplay();
  2314.     } else {
  2315.     text_sync();
  2316.     --Nsu;
  2317.     ep->Line = crow;
  2318.     ep->Column = column;
  2319.     text_load();
  2320.     if (erow != srow) {
  2321.         if (!text_sync()) {
  2322.         ++erow;
  2323.         if (erow - ep->Topline > Rows)
  2324.             erow = ep->Topline + Rows;
  2325.         SetAPen(Rp, 0);
  2326.         RectFill(Rp, COL(0), ROW(srow - ep->Topline), Xbase+Xpixs, ROW(erow - ep->Topline)-1);
  2327.         SetAPen(Rp, 1);
  2328.         text_displayseg(srow - ep->Topline, erow - srow);
  2329.         }
  2330.     } else {
  2331.         text_sync();
  2332.         if (moded)
  2333.         text_redisplaycurrline();
  2334.     }
  2335.     }
  2336.     if (column > Clen) {
  2337.     bset(Current+Clen, column - Clen, ' ');
  2338.     Current[column] = 0;
  2339.     }
  2340.     ep->Column = column;
  2341. }
  2342.  
  2343.  
  2344. do_tabstop()
  2345. {
  2346.     Ep->Tabstop = atoi(av[1]);
  2347. }
  2348.  
  2349.  
  2350. do_insertmode()
  2351. {
  2352.     register ED *ep = Ep;
  2353.  
  2354.     if (av[1][0]) {
  2355.     switch(av[1][1] & 0x1F) {
  2356.     case 'n'&0x1F:
  2357.         ep->Insertmode = 1;
  2358.         break;
  2359.     case 'f'&0x1F:
  2360.         ep->Insertmode = 0;
  2361.         break;
  2362.     case 'o'&0x1F:
  2363.         ep->Insertmode = 1 - ep->Insertmode;
  2364.         break;
  2365.     }
  2366.     if (ep->Insertmode)
  2367.         title("Insert mode on");
  2368.     else
  2369.         title("Insert mode off");
  2370.     }
  2371. }
  2372.  
  2373. do_insline()
  2374. {
  2375.     register ubyte *ptr;
  2376.     register ED *ep = Ep;
  2377.  
  2378.     ep->Modified = 1;
  2379.     text_sync();
  2380.     if (makeroom(32) && (ptr = allocb(1))) {
  2381.     bmovl(ep->List+ep->Line, ep->List+ep->Line+1,ep->Lines-ep->Line);
  2382.     ep->List[ep->Line] = ptr;
  2383.     *ptr = 0;
  2384.     ++ep->Lines;
  2385.     if (BEp == ep) {
  2386.         if (ep->Line < BSline)
  2387.         ++BSline;
  2388.         if (ep->Line <= BEline)
  2389.         ++BEline;
  2390.     }
  2391.     } else {
  2392.     nomemory();
  2393.     }
  2394.     text_load();
  2395.     if (Nsu == 0)
  2396.     ScrollRaster(Rp,0,-Ysize, COL(0), ROW(ep->Line-ep->Topline), COL(Columns)-1, ROW(Rows)-1);
  2397.     text_displayseg(ep->Line - ep->Topline, 1);
  2398. }
  2399.  
  2400. do_deline()
  2401. {
  2402.     register int delline;
  2403.     register ED *ep = Ep;
  2404.  
  2405.     if (ep->Lines > 1) {
  2406.     ep->Modified = 1;
  2407.     text_sync();
  2408.  
  2409.     FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1);
  2410.     bmovl(ep->List+ep->Line+1, ep->List+ep->Line,ep->Lines-ep->Line-1);
  2411.     if (BEp == ep) {
  2412.         if (ep->Line < BSline)
  2413.         --BSline;
  2414.         if (ep->Line <= BEline)
  2415.         --BEline;
  2416.     }
  2417.     delline = ep->Line;
  2418.     if (ep->Line >= --ep->Lines) {
  2419.         --ep->Line;
  2420.         text_load();
  2421.         if (ep->Line < ep->Topline) {
  2422.         if (Nsu == 0) {
  2423.             ep->Topline = ep->Line - (Rows>>1);
  2424.             if (ep->Topline < 0)
  2425.             ep->Topline = 0;
  2426.             text_redisplay();
  2427.         }
  2428.         return(0);
  2429.         }
  2430.     }
  2431.     text_load();
  2432.     if (Nsu == 0)
  2433.         ScrollRaster(Rp,0,Ysize, COL(0), ROW(delline-ep->Topline), COL(Columns)-1, ROW(Rows)-1);
  2434.     text_displayseg(Rows-1, 1);
  2435.     } else {
  2436.     do_firstcolumn();
  2437.     do_remeol();
  2438.     ep->Modified = 0;
  2439.     }
  2440. }
  2441.  
  2442. do_chfilename()
  2443. {
  2444.     text_sync();
  2445.     strncpy(Ep->Name, av[1], 63);
  2446.     MForceTitle = 1;
  2447. }
  2448.  
  2449. do_edit()
  2450. {
  2451.     long xfi;
  2452.     long oldlock;
  2453.     long lines;
  2454.     ubyte buf[256];
  2455.     ubyte *ptr;
  2456.     char failed = 1;
  2457.     register ED *ep = Ep;
  2458.  
  2459.     text_sync();
  2460.     if (*av[0] == 'n') {        /* newfile or insfile   */
  2461.     if (ep->Modified && getyn("Delete modified Image?") == 0)
  2462.         return(0);
  2463.     ep = uninit_init(ep);
  2464.     strncpy(ep->Name, av[1], 63);
  2465.     } else {
  2466.     ep->Modified = 1;
  2467.     }
  2468.     lines = ep->Lines;
  2469.     oldlock = CurrentDir(ep->dirlock);
  2470.     if (xfi = xfopen(av[1], "r", 4096)) {
  2471.     register int len;
  2472.     char oktitle = 1;
  2473.  
  2474.     title("Loading...");
  2475.     while ((len = xefgets(xfi, buf, 255)) >= 0) {
  2476.         failed = 0;
  2477.         if (makeroom(256) && (ptr = allocb(len+1))) {
  2478.         ep->List[ep->Lines++] = ptr;
  2479.         bmov(buf, ptr, len+1);
  2480.         } else {
  2481.         set_window_params();
  2482.         nomemory();
  2483.         oktitle = 0;
  2484.         break;
  2485.         }
  2486.     }
  2487.     set_window_params();
  2488.     if (oktitle)
  2489.         title("OK");
  2490.     } else {
  2491.     title("File Not Found");
  2492. #if AREXX
  2493.     cmderr = CMD_FAILED;
  2494. #endif
  2495.     }
  2496.     xfclose(xfi);
  2497.     CurrentDir(oldlock);
  2498.     if (ep->Lines != 1 && lines == 1 && ep->List[0][0] == 0) {
  2499.     ep->Modified = 0;
  2500.     ep->Line = 0;
  2501.     FreeMem(ep->List[0], strlen(ep->List[0])+1);
  2502.     bmovl(ep->List+1, ep->List,--ep->Lines);
  2503.     } else {
  2504.     if (!failed && lines <= ep->Lines - 1) {
  2505.         BEp = ep;
  2506.         BSline = lines;
  2507.         BEline = ep->Lines - 1;
  2508.         do_bmove();
  2509.     }
  2510.     }
  2511.     set_window_params();
  2512.     text_load();
  2513.     text_redisplay();
  2514. }
  2515.  
  2516.  
  2517. static char blockmode;
  2518.  
  2519. do_bsave()
  2520. {
  2521.     blockmode = 1;
  2522.     do_saveas();
  2523. }
  2524.  
  2525. do_save()
  2526. {
  2527.     av[1] = Ep->Name;
  2528.     do_saveas();
  2529. }
  2530.  
  2531. do_savetabs()
  2532. {
  2533.     Savetabs = (av[1][0] && av[1][1] == 'n') ? 1 : 0;
  2534. }
  2535.  
  2536. do_saveas()
  2537. {
  2538.     long oldlock;
  2539.     long xfi;
  2540.     register long i;
  2541.     register short j, k;
  2542.     register ubyte *ptr, *bp;
  2543.     long xs, xe;
  2544.     ubyte buf[256];
  2545.     char bm;
  2546.     ED *ep;
  2547.  
  2548.     bm = blockmode;
  2549.     if (blockmode && blockok()) {
  2550.     xs = BSline;
  2551.     xe = BEline + 1;
  2552.     ep = BEp;
  2553.     } else {
  2554.     xs = 0;
  2555.     xe = Ep->Lines;
  2556.     ep = Ep;
  2557.     }
  2558.     blockmode = 0;
  2559.     text_sync();
  2560.     oldlock = CurrentDir(Ep->dirlock);
  2561.     if (Wbs && Wdisable == 0) {     /* Write out .info file */
  2562.     DISKOBJ sdo, *d;
  2563.     bzero(&sdo, sizeof(sdo));
  2564.     if ((d = GetDiskObject(av[1])) == NULL) {
  2565.         if (getpath(Wbs->sm_ArgList[0].wa_Name, buf)) {
  2566.         sdo.do_Magic = WB_DISKMAGIC;
  2567.         sdo.do_Version = WB_DISKVERSION;
  2568.         makemygadget(&sdo.do_Gadget);
  2569.         sdo.do_Type = WBPROJECT;
  2570.         sdo.do_DefaultTool = (char *)buf;
  2571.         sdo.do_ToolTypes = NULL;
  2572.         sdo.do_CurrentX = NO_ICON_POSITION;
  2573.         sdo.do_CurrentY = NO_ICON_POSITION;
  2574.         sdo.do_DrawerData = NULL;
  2575.         sdo.do_ToolWindow = NULL;
  2576.         sdo.do_StackSize = 8192;
  2577.         PutDiskObject(av[1], &sdo);
  2578.         }
  2579.     } else {
  2580.         FreeDiskObject(d);
  2581.     }
  2582.     }
  2583.     if (xfi = xfopen(av[1], "w", 4096)) {
  2584.     title("Saving...");
  2585.     for (i = xs; i < xe; ++i) {
  2586.         ptr = ep->List[i];
  2587.         if (Savetabs) {
  2588.         for (bp = buf, j = 0; *ptr; ++ptr, ++bp, j = (j+1)&7) {
  2589.             *bp = *ptr;
  2590.             if (j == 7 && *bp == ' ' && *(bp-1) == ' ') {
  2591.             k = j;
  2592.             while (k-- >= 0 && *bp == ' ')
  2593.                 --bp;
  2594.             *++bp = 9;
  2595.             } else {
  2596.             if (*bp == '\"' || *bp == '\'' || *bp == '\`' || *bp == '(')
  2597.                 break;
  2598.             }
  2599.         }
  2600.         strcpy(bp, ptr);
  2601.         ptr = buf;
  2602.         }
  2603.         xfwrite(xfi, ptr, strlen(ptr));
  2604.         if (xfwrite(xfi, "\n", 1)) {
  2605.         xfclose(xfi);
  2606.         goto err;
  2607.         }
  2608.     }
  2609.     if (xfclose(xfi)) {
  2610. err:        Abortcommand = 1;
  2611.         title("WRITE FAILED!");
  2612.     } else {
  2613.         ep->Modified &= bm;
  2614.         title("OK");
  2615.     }
  2616.     } else {
  2617.     title("Unable to open write file");
  2618.     Abortcommand = 1;
  2619.     }
  2620.     CurrentDir(oldlock);
  2621. }
  2622.  
  2623. do_block()          /* block, unblock   */
  2624. {
  2625.     text_sync();
  2626.  
  2627.     switch(av[0][0]) {
  2628.     case 'b':
  2629.     if (BSline < 0) {
  2630. bstart:
  2631.         BEp = Ep;
  2632.         BSline = Ep->Line;
  2633.         title("Block Begin");
  2634.     } else {
  2635.         if (BEline > -1) {
  2636.         title("Block Already Marked");
  2637.         break;
  2638.         }
  2639.         if (BEp != Ep)
  2640.         goto bstart;
  2641.         title("Block End");
  2642.         BEline = Ep->Line;
  2643.         if (BSline > BEline) {
  2644.         BEline = BSline;
  2645.         BSline = Ep->Line;
  2646.         }
  2647.         text_redrawblock(1);
  2648.     }
  2649.     break;
  2650.     case 'u':
  2651.     text_redrawblock(0);
  2652.     title ("Block Unmarked");
  2653.     break;
  2654.     }
  2655. }
  2656.  
  2657.  
  2658. blockok()
  2659. {
  2660.     if (BEp && BSline >= 0 && BSline <= BEline && BEline < BEp->Lines)
  2661.     return(1);
  2662.     BEp = NULL;
  2663.     BSline = BEline = -1;
  2664.     title("Block Not Specified");
  2665.     return(0);
  2666. }
  2667.  
  2668.  
  2669. do_bdelete()
  2670. {
  2671.     register long i, n;
  2672.     register ED *bep = BEp;
  2673.     register WIN *savewin = Ep->Win;
  2674.  
  2675.     if (blockok()) {
  2676.     text_switch(bep->Win);
  2677.     n = BEline - BSline + 1;
  2678.     if (bep->Line >= BSline && bep->Line <= BEline)
  2679.         bep->Line = BSline;
  2680.     if (bep->Line > BEline)
  2681.         bep->Line -= n;
  2682.     freelist(bep->List + BSline, BEline - BSline + 1);
  2683.     bmovl(bep->List+BEline+1,bep->List+BSline,(bep->Lines-BEline-1));
  2684.     bep->Lines -= n;
  2685.     bep->Modified = 1;
  2686.     if (bep->Line >= bep->Lines)
  2687.         bep->Line = bep->Lines - 1;
  2688.     if (bep->Line < 0)
  2689.         bep->Line = 0;
  2690.     if (bep->Lines == 0)
  2691.         bep = uninit_init(bep);
  2692.     text_load();
  2693.     BEp = NULL;
  2694.     BSline = BEline = -1;
  2695.     if (!text_sync())
  2696.         text_redisplay();
  2697.     text_switch(savewin);
  2698.     }
  2699. }
  2700.  
  2701. void
  2702. do_bcopy()
  2703. {
  2704.     register ubyte **list;
  2705.     register long lines, i;
  2706.     register ED *ep = Ep;
  2707.  
  2708.     text_sync();
  2709.     if (!blockok())
  2710.     return;
  2711.     if (ep == BEp && ep->Line > BSline && ep->Line <= BEline) {
  2712.     title("Cannot Move into self");
  2713.     return;
  2714.     }
  2715.     lines = BEline - BSline + 1;
  2716.     if (extend(ep, lines)) {
  2717.     if (list = (ubyte **)allocl(lines)) {
  2718.         bmovl(BEp->List+BSline,list,lines);
  2719.         bmovl(ep->List+ep->Line, ep->List+ep->Line+lines, ep->Lines-ep->Line);
  2720.         for (i = 0; i < lines; ++i) {
  2721.         ubyte *str = allocb(strlen(list[i])+1);
  2722.         if (!str) {
  2723.             nomemory();
  2724.             FreeMem(list, lines * sizeof(char *));
  2725.             freelist(ep->List + Ep->Line, i);
  2726.             bmovl(ep->List+ep->Line+lines, ep->List+ep->Line, ep->Lines-ep->Line);
  2727.             return;
  2728.         }
  2729.         strcpy(str, list[i]);
  2730.         ep->List[ep->Line+i] = str;
  2731.         }
  2732.         FreeMem(list, lines * sizeof(char *));
  2733.     }
  2734.     }
  2735.     if (ep == BEp && ep->Line <= BSline) {
  2736.     BSline += lines;
  2737.     BEline += lines;
  2738.     }
  2739.     ep->Modified = 1;
  2740.     ep->Lines += lines;
  2741.     text_load();
  2742.     if (!text_sync())
  2743.     text_redisplay();
  2744. }
  2745.  
  2746.  
  2747. void
  2748. do_bmove()
  2749. {
  2750.     register long lines;
  2751.     register ubyte **list;
  2752.     register ED *ep = Ep;
  2753.  
  2754.     text_sync();
  2755.     if (!blockok())
  2756.     return;
  2757.     if (BEp == ep && ep->Line >= BSline && ep->Line <= BEline) {
  2758.     title("Cannot Move into self");
  2759.     return;
  2760.     }
  2761.     lines = BEline - BSline + 1;
  2762.     if (!(list = (ubyte **)allocl(lines))) {
  2763.     nomemory();
  2764.     return;
  2765.     }
  2766.     BEp->Modified = ep->Modified = 1;
  2767.     bmovl(BEp->List + BSline, list, lines);
  2768.     if (ep == BEp) {
  2769.     if (ep->Line > BSline) {
  2770.         bmovl(ep->List+BEline+1, ep->List+BSline, ep->Line-BEline-1);
  2771.         bmovl(list, ep->List + ep->Line - lines, lines);
  2772.     } else {
  2773.         bmovl(ep->List+ep->Line, ep->List+ep->Line+lines, BSline-ep->Line);
  2774.         bmovl(list, ep->List + ep->Line, lines);
  2775.     }
  2776.     } else {
  2777.     WIN *savewin = ep->Win;
  2778.     if (extend(ep, lines)) {
  2779.         bmovl(BEp->List+BEline+1, BEp->List+BSline, BEp->Lines-BEline-1);
  2780.         bmovl(ep->List+ep->Line, ep->List+ep->Line+lines, ep->Lines-ep->Line);
  2781.         bmovl(list, ep->List+ep->Line, lines);
  2782.         ep->Lines += lines;
  2783.         BEp->Lines -= lines;
  2784.         if (BEp->Line >= BSline && BEp->Line <= BEline)
  2785.         BEp->Line = BSline - 1;
  2786.         if (BEp->Line > BEline)
  2787.         BEp->Line -= lines;
  2788.         if (BEp->Line < 0)
  2789.         BEp->Line = 0;
  2790.         BSline = BEline = -1;
  2791.         if (BEp->Lines == 0) {
  2792.         register ubyte *ptr = allocb(1);
  2793.         BEp->List[0] = ptr;
  2794.         *ptr = 0;
  2795.         ++BEp->Lines;
  2796.         }
  2797.         text_load();
  2798.         text_switch(BEp->Win);
  2799.         BEp = NULL;
  2800.         ep = Ep;
  2801.         if (!ep->iconmode) {
  2802.         if (!text_sync())
  2803.             text_redisplay();
  2804.         }
  2805.         text_switch(savewin);
  2806.         ep = Ep;
  2807.     }
  2808.     }
  2809.     BSline = BEline = -1;
  2810.     BEp = NULL;
  2811.     FreeMem(list, lines * sizeof(char *));
  2812.     ep->Modified = 1;
  2813.     text_load();
  2814.     if (!text_sync())
  2815.     text_redisplay();
  2816. }
  2817.  
  2818.  
  2819. /*
  2820.  * IF condition trueaction, IFELSE condition trueaction falseaction
  2821.  *
  2822.  *  condition:    !condition NOT the specified condition.
  2823.  *        #       toggle number is SET
  2824.  *        top       top of file (on first line)
  2825.  *        bot       end of file (on last line)
  2826.  *        left       start of line (leftmost column)
  2827.  *        right       end of line (nothing but spaces under and to the right)
  2828.  *        modified   text has been modified
  2829.  *        insert       currently in insert mode
  2830.  *        y[<=>]#    cursor is (any OR combo of <,>,=) row #  (line numbers start at 1)
  2831.  *        x[<=>]#    cursor is (<,>,<=,>=,<>) column #        (columns start at 1)
  2832.  *                <> means 'not equal'
  2833.  *
  2834.  *        cl       char under cursor is lower case
  2835.  *        cu       char under cursor is upper case
  2836.  *        ca       char under cursor is alpha
  2837.  *        cn       char under cursor is numeric
  2838.  *        cb       char within selected block
  2839.  *        c[<=>]#    char under cursor is (combo of <,>,and =) #
  2840.  */
  2841.  
  2842. do_if()
  2843. {
  2844.     char haselse = (av[0][2] == 'e');
  2845.     char iswhile = (av[0][0] == 'w');
  2846.     char istrue, notop = 0;
  2847.     char c, cx, cc;
  2848.     ubyte *buf1, *buf2;
  2849.     register ubyte *ptr;
  2850.     register ED *ep = Ep;
  2851.     int i, cxn, cn;
  2852.  
  2853.     buf1 = (ubyte *)malloc(256);
  2854.     buf2 = (ubyte *)malloc(256);
  2855.     if (buf1 == NULL || buf2 == NULL) {
  2856.     if (buf1) free(buf1);
  2857.     if (buf2) free(buf2);
  2858.     title("No Memory!");
  2859.     return(0);
  2860.     }
  2861.     breakreset();
  2862.     ptr = av[1];
  2863.     if (*ptr == '!') {
  2864.     notop = 1;
  2865.     ++ptr;
  2866.     }
  2867.     c = ptr[0];
  2868.     cn= atoi(ptr);
  2869.     cx= ptr[1];
  2870.     cxn=atoi(ptr+1);
  2871.     strcpy(buf1, av[2]);
  2872.  
  2873. loop:
  2874.     istrue = 0;
  2875.     i = 0;
  2876.     switch(c) {
  2877.     case 'x':
  2878.     i = ep->Column + 1;
  2879.     case 'y':
  2880.     if (!i)
  2881.         i = ep->Line + 1;
  2882. conditional:
  2883.     {
  2884.         register int j, n;
  2885.         char any = 0;
  2886.  
  2887.         for (j = 1; ptr[j] && (ptr[j]<'0'||ptr[j]>'9'); ++j);
  2888.         n = atoi(ptr+j);
  2889.         for (j = 1; ptr[j]; ++j) {
  2890.         switch(ptr[j]) {
  2891.         case '<':
  2892.             any = 1;
  2893.             if (i < n)
  2894.             istrue = 1;
  2895.             break;
  2896.         case '=':
  2897.             any = 1;
  2898.             if (i == n)
  2899.             istrue = 1;
  2900.             break;
  2901.         case '>':
  2902.             any = 1;
  2903.             if (i > n)
  2904.             istrue = 1;
  2905.             break;
  2906.         }
  2907.         }
  2908.         if (!any && i == n)  /* default is equivalence   */
  2909.         istrue = 1;
  2910.     }
  2911.     break;
  2912.     case 't':
  2913.     istrue = ep->Line == 0;
  2914.     break;
  2915.     case 'b':
  2916.     istrue = ep->Line == ep->Lines-1;
  2917.     break;
  2918.     case 'l':
  2919.     istrue = ep->Column == 0;
  2920.     break;
  2921.     case 'r':
  2922.     istrue = ep->Column == Clen;
  2923.     break;
  2924.     case 'm':
  2925.     text_sync();
  2926.     istrue = ep->Modified != 0;
  2927.     break;
  2928.     case 'i':
  2929.     istrue = ep->Insertmode != 0;
  2930.     break;
  2931.     case 'c':
  2932.     cc = Current[ep->Column];
  2933.     switch(cx) {
  2934.     case 'b':
  2935.         istrue = BEp == ep && ep->Line >= BSline && ep->Line <= BEline;
  2936.         break;
  2937.     case 'l':
  2938.         istrue = cc >= 'a' && cc <= 'z';
  2939.         break;
  2940.     case 'u':
  2941.         istrue = cc >= 'A' && cc <= 'Z';
  2942.         break;
  2943.     case 'a':
  2944.         istrue = (cc>='a'&&cc<='z')||(cc>='A'&&cc<='Z')||(cc>='0'&&cc<='9');
  2945.         break;
  2946.     case 'n':
  2947.         istrue = (cc >= '0' && cc <= '9');
  2948.         break;
  2949.     default:        /* c[<=>]#  */
  2950.         i = Current[ep->Column];
  2951.         goto conditional;
  2952.         break;
  2953.     }
  2954.     break;
  2955.     default:
  2956.     if (c >= '0' && c <= '9')
  2957.         istrue = do_toggle(cn) != 0;
  2958.     else
  2959.         title("bad conditional");
  2960.     break;
  2961.     }
  2962.     istrue ^= notop;
  2963.     if (istrue) {
  2964.     strcpy(buf2, buf1);     /* could be executed multiple times */
  2965.     if (do_command(buf2) == 0)
  2966.         goto done;
  2967.     if (iswhile) {
  2968.         if (breakcheck())
  2969.         Abortcommand = 1;
  2970.         else
  2971.         goto loop;
  2972.     }
  2973.     } else {
  2974.     if (haselse) {          /* only executed once */
  2975.         strcpy(buf2, av[3]);
  2976.         do_command(buf2);
  2977.     }
  2978.     }
  2979. done:
  2980.     free(buf1);
  2981.     free(buf2);
  2982. }
  2983.  
  2984.  
  2985. /*
  2986.  * TOGGLE #, SETTOGGLE #, RESETTOGGLE #
  2987.  */
  2988.  
  2989. do_toggle(n)
  2990. {
  2991.     static char tg[MAXTOGGLE];
  2992.     register int i;
  2993.  
  2994.     if (n >= 0) {
  2995.     if (n >= MAXTOGGLE)
  2996.         return(0);
  2997.     return(tg[n]);
  2998.     }
  2999.     i = atoi(av[1]);
  3000.     if (i >= 0 && i < MAXTOGGLE) {
  3001.     switch(av[0][0]) {
  3002.     case 't':
  3003.         tg[i] = !tg[i];
  3004.         break;
  3005.     case 's':
  3006.         tg[i] = 1;
  3007.         break;
  3008.     case 'r':
  3009.         tg[i] = 0;
  3010.         break;
  3011.     }
  3012.     }
  3013. }
  3014.  
  3015.  
  3016. do_tlate()
  3017. {
  3018.     register ubyte *ptr = av[1];
  3019.     register ED *ep = Ep;
  3020.     register char c = Current[ep->Column];
  3021.  
  3022.     if (c == 0)
  3023.     c = ' ';
  3024.     if (ptr[0] == '+')
  3025.     c += atoi(ptr+1);
  3026.     else
  3027.     if (ptr[0] == '-')
  3028.     c -= atoi(ptr+1);
  3029.     else
  3030.     c = atoi(ptr);
  3031.     if (c) {
  3032.     if (Current[ep->Column] == 0) {
  3033.         Clen = ep->Column + 1;
  3034.         Current[Clen] = 0;
  3035.     }
  3036.     Current[ep->Column] = c;
  3037.     if (Nsu == 0) {
  3038.         movetocursor();
  3039.         setpen(ep->Line);
  3040.         Text(Rp, Current+ep->Column, 1);
  3041.     }
  3042.     }
  3043. }
  3044.  
  3045. /*
  3046.  *  BSOURCE
  3047.  *
  3048.  *  note that since the start and end lines are loaded immediately and the
  3049.  *  block unblock'd before execution starts, you can theoretically have
  3050.  *  another BSOURCE as part of this BSOURCE (but be carefull!).
  3051.  */
  3052.  
  3053. do_bsource()
  3054. {
  3055.     ubyte buf[256];
  3056.     register int i, sl, se;
  3057.  
  3058.     if (blockok()) {
  3059.     sl = BSline;
  3060.     se = BEline + 1;
  3061.     for (i = sl; BEp && i < se && i < BEp->Lines; ++i) {
  3062.         text_sync();        /* make sure we are using latest text */
  3063.         strcpy(buf, BEp->List[i]);
  3064.         if (do_command(buf) == 0)
  3065.         break;
  3066.     }
  3067.     text_redrawblock(0);
  3068.     }
  3069. }
  3070.  
  3071. /*
  3072.  *  SCANF controlstring
  3073.  *
  3074.  *  The C scanf routine.  Only one variable, a string, is allowed in the
  3075.  *  control string.
  3076.  */
  3077.  
  3078. void
  3079. do_scanf()
  3080. {
  3081.     char buf[256];
  3082.  
  3083.     buf[0] = 0;
  3084.     sscanf(Current+Ep->Column,av[1],buf,buf,buf,buf,buf,buf,buf);
  3085.     if (String)
  3086.     free(String);
  3087.     String = (char *)malloc(strlen(buf)+1);
  3088.     strcpy(String,buf);
  3089.     title(String);
  3090. }
  3091.  
  3092. movetocursor()
  3093. {
  3094.     register ED *ep = Ep;
  3095.     Move(Rp, XTbase+(ep->Column-ep->Topcolumn)*Xsize, YTbase+(ep->Line-ep->Topline)*Ysize);
  3096. }
  3097.  
  3098. extend(ep, lines)
  3099. register ED *ep;
  3100. {
  3101.     register long extra = ep->Maxlines - ep->Lines;
  3102.     register ubyte **list;
  3103.  
  3104.     if (lines > extra) {
  3105.     lines += ep->Lines;
  3106.     if (list = (ubyte **)allocl(lines)) {
  3107.         bmovl(ep->List, list, ep->Lines);
  3108.         FreeMem(ep->List, sizeof(char *) * ep->Maxlines);
  3109.         ep->Maxlines = lines;
  3110.         ep->List = list;
  3111.         return(1);
  3112.     }
  3113.     nomemory();
  3114.     return(0);
  3115.     }
  3116.     return(1);
  3117. }
  3118.  
  3119. makeroom(n)
  3120. {
  3121.     register ED *ep = Ep;
  3122.     if (ep->Lines >= ep->Maxlines)
  3123.     return(extend(ep, n));
  3124.     return(1);
  3125. }
  3126.  
  3127. freelist(list, n)
  3128. register char **list;
  3129. {
  3130.     while (n) {
  3131.     FreeMem(list[0], strlen(list[0])+1);
  3132.     ++list;
  3133.     --n;
  3134.     }
  3135. }
  3136.  
  3137. \Rogue\Monster\
  3138. else
  3139.   echo "will not over write ./src/cmd2.c"
  3140. fi
  3141. if [ `wc -c ./src/cmd2.c | awk '{printf $1}'` -ne 23079 ]
  3142. then
  3143. echo `wc -c ./src/cmd2.c | awk '{print "Got " $1 ", Expected " 23079}'`
  3144. fi
  3145. echo "Finished archive 2 of 6"
  3146. # if you want to concatenate archives, remove anything after this line
  3147. exit
  3148. -- 
  3149. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  3150. Have five nice days.
  3151.